2014-10-02 142 views
2

我在使用Minitest的Ruby应用程序中开始使用DDD和TDD。 我创建了一个存储库类(没有数据库访问,但它为我生成实体)。这是一个单身人士。我如何测试(TDD)单例类?

我想测试实体的生成。问题在于,因为它是单身人士,测试的执行顺序会影响结果。

有没有办法强制处理单身元素,所以它是“新鲜的”?

这里是我的仓库代码:

require "singleton" 

class ParticipantRepository 
    include Singleton 

    def initialize() 
     @name_count = 0 
    end 

    def generate_participant() 
     participant = Participant.new 
     participant.name = "Employee#{get_name_count()}" 
     return participant 
    end 

    private 
    def get_name_count() 
     old_name_count = @name_count 
     @name_count += 1 
     return old_name_count 
    end 
end 

而且测试:

require_relative 'test_helper' 


class ParticipantRepositoryTest < MiniTest::Unit::TestCase 

    def setup() 
     @repository = ParticipantRepository.instance 
    end 

    def test_retrieve_participant 
     participant = @repository.generate_participant 

     refute_nil participant 
     refute_nil participant.name 
     refute_equal("", participant.name) 
     assert_equal(0, participant.subordinates_count) 
    end 

    def test_employee_name_increment 
     participant1 = @repository.generate_participant 
     participant2 = @repository.generate_participant 

     refute_equal(participant1.name, participant2.name) 

     index_participant1 = /Employee([0-9]+)/.match(participant1.name)[1] 
     index_participant2 = /Employee([0-9]+)/.match(participant2.name)[1] 

     assert_equal(0, index_participant1.to_i) 
     assert_equal(1, index_participant2.to_i) 
    end 

end 

断言assert_equal(0, index_participant1.to_i)时,首先执行test_employee_name_increment成功,如果最后执行的失败。

我想能够测试存储库(因为它会演变成更大的东西)。我怎样才能做到这一点?

谢谢!

+0

单身人士和可测试性往往不一致。考虑使用某种类型的DI来执行单例,而不是让班级担心这一点。 – 2014-10-02 23:10:02

+0

@MattBall这将是伟大的。你会有任何关于如何使用DI解决这个问题的参考? – JSBach 2014-10-02 23:54:01

+0

没什么特别的;我不写Ruby。看看:http://stackoverflow.com/search?q=ruby+dependency+injection – 2014-10-03 01:15:08

回答

5

订购你的测试都不会有问题。为了正确测试一个单例类,你需要像对待实例一样对待它。要做到这一点,在安装过程中将您的单身包裹在匿名类中。每次设置被调用时,您都会得到一个未被触动的ParticipantRepository副本:

def setup 
    @repository = Class.new(ParticipantRepository).instance 
end 
+0

还有其他几个选项(我认为@ MicahJaffe的答案就在这里):http://stackoverflow.com/a/12128594/3367343。虽然我喜欢这个。 – thohl 2014-10-03 18:47:59

2

打电话i_suck_and_my_tests_are_order_dependent!()在 顶部测试时,您绝对肯定需要进行有序测试。在 这样做,你承认你吸吮,你的测试很弱。

...我保证我没有写这个方法或文档。

欲了解更多信息,请参见:http://www.ruby-doc.org/stdlib-2.0/libdoc/minitest/rdoc/MiniTest/Unit/TestCase.html#method-c-i_suck_and_my_tests_are_order_dependent-21

+0

哇,这是一个意想不到的方法名称:p我会尝试更改我的架构以避免使用此问题。顺便说一下,任何想法 – JSBach 2014-10-02 23:51:11

+0

,测试不是顺序依赖自己。问题是我期望有一个给定的值,但使用的实例不是“新鲜”的,因为它是一个单例。解决单身问题解决了订单依赖问题 – JSBach 2014-10-03 00:03:45