4

我正在尝试测试命名空间中的一些类,目前我有以下代码:

describe Server::SessionController do

  it "should create session" do
    Server::LoginController.stub(:authenitcate).and_return(session_id)
    Server::SessionController....
    Server::SessionController....
  end
end

如何摆脱可重复的Server命名空间?

4

2 回答 2

5

RSpec Book ( http://pragprog.com/book/achbd/the-rspec-book ) 提供了一个解决方案:

3 module Codebreaker
4    describe Game do
5        describe "#start" do

...第二条语句声明了一个名为 Codebreaker 的 Ruby 模块。这对于运行规范不是必需的,但它提供了一些便利。例如,我们不必完全限定第 4 行的 Game。

所以,试着把你的规范放在一个Server模块中。HTH。

于 2013-01-22T14:57:15.037 回答
2

虽然@BernardK 提供了适合大多数情况的“正确的”解决方案,但也有一个肮脏的 HACK。如果您有很多不同的 Spec 文件测试来自同一命名空间的不同类,并且厌倦了module Your::Long::Namespace ... end在每个文件中编写并引入额外的标识级别(因为这可能会导致 VCS 中的巨大差异),这可能会很有用。

所以,如果你把这个...

def Object.const_missing(c)
  if Your::Long::Namespace.const_defined? c
    Your::Long::Namespace.const_get(c)
  else
    raise NameError, "uninitialized constant #{c}"
  end
end

...在您的spec_helper.rb, 然后在使用此帮助程序的每个规范中,您将能够使用来自Your::Long::Namespace(类也是常量)的所有常量,无需前缀,也无需将您的规范放入此模块中。这很像 C++ 的using namespace声明。你可以在我的一个旧项目中看到一个使用它的例子:定义在这里使用例子在这里

但请注意:

  • 这违反了所有可以想到的 OOP 原则;
  • 你修改了所有对象的行为,一些代码可能不会这样;
  • 与 C++ 一样using namespace,这会导致命名空间混乱和可能的冲突;
  • 保持沉默并且不注意(这很好),这种黑客非常不明显且不可调试(这非常糟糕,特别是如果您有合作者)。

你看,使用风险自负:)

于 2013-01-22T16:46:31.807 回答