Rails:如何为ruby模块编写testing?

我想知道如何编写一个模块的unit testing,混合到几个类,但不知道如何去做:

  1. 我是否通过在其中一个包含它们的类的testing文件中编写testing来testing实例方法(看起来不正确),还是可以以某种方式将包含的方法的testing保存在特定于模块的单独文件中?

  2. 同样的问题适用于类方法。

  3. 我是否应该为模块中的每个类提供单独的testing文件,就像普通的rails模型一样,或者是否存在于通用模块testing文件中?

恕我直言,你应该做的functiontesting覆盖范围将覆盖模块的所有用途,然后在unit testing中隔离testing:

setup do @object = Object.new @object.extend(Greeter) end should "greet person" do @object.stubs(:format).returns("Hello {{NAME}}") assert_equal "Hello World", @object.greet("World") end should "greet person in pirate" do @object.stubs(:format).returns("Avast {{NAME}} lad!") assert_equal "Avast Jim lad!", @object.greet("Jim") end 

如果你的unit testing是好的,你应该能够对混入模块的function进行抽烟testing。

要么…

编写一个testing助手,声明正确的行为,然后使用它来对每个混合类。用法如下:

 setup do @object = FooClass.new end should_act_as_greeter 

如果你的unit testing是好的,这可以是一个简单的烟雾testing预期的行为,检查正确的代表被称为等

使用内联类(我没有做任何奇特的flexmock或stubba / mocha用法来显示点)

 def test_should_callout_to_foo m = Class.new do include ModuleUnderTest def foo 3 end end.new assert_equal 6, m.foo_multiplied_by_two end 

在那里的任何嘲笑/存根库应该给你一个更干净的方式来做到这一点。 你也可以使用结构:

  instance = Struct.new(:foo).new class<<instance include ModuleUnderTest end instance.foo = 4 

如果我有一个在许多地方使用的模块,我有一个unit testing,就这样做(在模块方法下滑动一个testing对象,并testing模块方法是否在该对象上正常工作)。

我试图保持我的testing只关注该特定类/模块的合同。 如果我已经在该模块的testing类中certificate了该模块的行为(通常将该模块包含在该模块规范中声明的testing类中),那么我将不会为使用该模块的生产类复制该testing。 但是,如果还有其他行为需要testing生产类或集成问题,那么我会为生产类编写testing。

例如我有一个名为AttributeValidator的模块,执行类似于ActiveRecord轻量级validation。 我在模块规范中编写模块行为的testing:

 before(:each) do @attribute_validator = TestAttributeValidator.new end describe "after set callbacks" do it "should be invoked when an attribute is set" do def @attribute_validator.after_set_attribute_one; end @attribute_validator.should_receive(:after_set_attribute_one).once @attribute_validator.attribute_one = "asdf" end end class TestAttributeValidator include AttributeValidator validating_str_accessor [:attribute_one, /\d{2,5}/] end 

现在,在包含模块的生产类中,我不会重新声明callback已经生成,但是我可以断言包含的类具有特定的正则expression式的特定validation集,对于该类特定的某些特定的validation集重现我为模块写的testing。 在生产类的规范中,我想保证设置了特定的validation,但是validation通常不起作用。 这是一种集成testing,但不会重复我为模块做出的相同的断言:

 describe "ProductionClass validation" do it "should return true if the attribute is valid" do @production_class.attribute = @valid_attribute @production_class.is_valid?.should be_true end it "should return false if the attribute is invalid" do @production_class.attribute = @invalid_attribute @production_class.is valid?.should be_false end end 

这里有一些重复(如大多数集成testing将有),但testingcertificate了两个不同的东西给我。 一组testingcertificate了模块的一般行为,另一组testingcertificate了使用该模块的生产类的特定实现问题。 从这些testing中,我知道模块将validation属性并执行callback,并且我知道我的生产类对于生产类特有的特定标准具有一组特定的validation。

希望有所帮助。

我通常会尽可能多的隔离模块来testing模块,本质上是testing这些方法,只需要足够的代码,模拟和存根来实现它。

那么我可能也会对这些模块所包含的类进行testing。我可能不会testing每个类,但是会testing足够多的类以获得良好的覆盖率,并能够洞察出现的任何问题。 这些testing不需要明确地testing模块,但肯定会testing它在特定情况下的使用情况。

每组testing都有自己的文件。