【问题标题】:rspec issue while testing two classes with the same name under different namespaces (modules)在不同的命名空间(模块)下测试两个具有相同名称的类时出现 rspec 问题
【发布时间】:2018-07-27 20:52:19
【问题描述】:

免责声明:

  • 我对 ruby​​ 还是很陌生
  • 请不要问我为什么在两个不同的模块中使用相同的类名。我只是想了解为什么 rspec 会这样。我觉得很困惑,无法在网上找到答案。

问题描述:

  • 我在 /lib 中有两个 .rb 文件。
  • 两者都有一个名为 FooClass,但在不同的模块下(NamespaceOne,NamespaceTwo)。
  • 然而,当我运行 rspec 时,一个测试失败,因为它针对错误的类运行,并且失败消息看起来很奇怪,即失败消息的一部分暗示它正在查看 NamespaceOne,而很明显它实际上尝试运行针对 NamespaceTwo 进行测试。

我的问题:为什么 rspec 会这样?我错过了什么?

这是我在 lib 文件夹中的内容:

lib/one.rb:

module NamespaceOne

  class FooClass
    def self.method_one(input)
      1
    end
  end
end

lib/two.rb:

module NamespaceTwo

  class FooClass
    def self.method_two(input)
      2
    end
  end
end

,这里有两个对应的规范:

spec/one_spec.rb

require "one"

include NamespaceOne

describe FooClass do

    describe ".method_one" do
        context "given an empty string" do
            it "returns 1" do
                expect(FooClass.method_one("")).to eql(1)
            end
        end
    end

end

和spec/two_spec.rb

require "two"

include NamespaceTwo

describe FooClass do

    describe ".method_two" do
        context "given an empty string" do
            it "returns 2" do
                expect(FooClass.method_two("")).to eql(2)
            end
        end
    end

end

最后,rspec 输出:

$ bundle exec rspec --format documentation

NamespaceOne::FooClass
  .method_one
    given an empty string
      returns 1 (FAILED - 1)

NamespaceTwo::FooClass
  .method_two
    given an empty string
      returns 2

Failures:

  1) NamespaceOne::FooClass.method_one given an empty string returns 1
     Failure/Error: expect(FooClass.method_one("")).to eql(1)

     NoMethodError:
       undefined method `method_one' for NamespaceTwo::FooClass:Class
       Did you mean?  method_two
     # ./spec/one_spec.rb:10:in `block (4 levels) in <top (required)>'

Finished in 0.00201 seconds (files took 0.08006 seconds to load)
2 examples, 1 failure

Failed examples:

rspec ./spec/one_spec.rb:9 # NamespaceOne::FooClass.method_one given an empty string returns 1

注意:在测试/示例中,如果我使用完整命名空间调用方法,则测试确实通过了。即在各自的规范文件中进行以下调整使测试通过,

spec/one_spec.rb

expect(NamespaceOne::FooClass.method_one("")).to eql(1)

spec/two_spec.rb

expect(NamespaceTwo::FooClass.method_two("")).to eql(2)

但我不明白为什么像我所做的那样“包含”模块是不够的。

【问题讨论】:

  • 我回答你的问题了吗?

标签: ruby rspec


【解决方案1】:

当你这样做时

require "one"

include NamespaceOne

describe FooClass do

您将NamespaceOne 包含在Object 中,但ruby 不知道下一个命名空间FooClass 应该解析为NamspaceOne。那是因为它是按词法完成的 (https://stackoverflow.com/a/20848317/3109182)。而是在描述时使用完整的命名空间,这样 rspec 和 ruby​​ 就知道要解析到哪些常量:

require "one"    
describe NamespaceOne::FooClass do
end

【讨论】:

    猜你喜欢
    • 2017-05-18
    • 2014-01-12
    • 2011-05-29
    • 2010-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多