如何测试单例类?

时间:2022-10-30 09:19:00

I am starting with DDD and TDD in a Ruby application using Minitest. I created a repository class (no database access, but it generates the entities for me). It is a singleton.

我从使用Minitest的Ruby应用程序中的DDD和TDD开始。我创建了一个repository类(没有数据库访问权限,但它为我生成实体)。这是一个单例。

I would like to test the generation of the entities. The problem is that because it is a singleton, the order of executions of the tests affect the results.

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

Is there any way to force the disposal of the singleton element so it is "fresh"?

有没有办法强制处理单元素,使它“新鲜”?

Here is my repository code:

以下是我的存储库代码:

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

And the tests:

和测试:

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

The assertion assert_equal(0, index_participant1.to_i) succeeds when test_employee_name_increment is executed first and fails if it is executed last.

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

I would like to be able to test the repository (because it will evolve into something bigger). How can I do that?

我希望能够测试存储库(因为它将演变成更大的东西)。我怎么做呢?

Thanks!

谢谢!

2 个解决方案

#1


5  

Ordering your tests won't matter. To properly test a singleton class you need to treat it like an instance object. To do that, wrap your singleton in an anonymous Class during setup. Every time setup is called you'll get an untouched copy of the ParticipantRepository:

排序测试并不重要。要正确地测试单例类,需要将其视为实例对象。为此,在安装期间将单例对象包装在一个匿名类中。每次调用setup时,你会得到一个未受影响的参与者副本:

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

#2


2  

Call i_suck_and_my_tests_are_order_dependent!() at the top of your tests when you absolutely positively need to have ordered tests. In doing so, you’re admitting that you suck and your tests are weak.

当您绝对需要进行有序测试时,请在测试的顶部调用i_suck_and_my_tests_are_order_dependent!()。这样做,你就承认自己很差劲,你的考试也很差。

...I promise I didn't write this method or the docs.

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

For more info, see: 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

有关更多信息,请参见: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

#1


5  

Ordering your tests won't matter. To properly test a singleton class you need to treat it like an instance object. To do that, wrap your singleton in an anonymous Class during setup. Every time setup is called you'll get an untouched copy of the ParticipantRepository:

排序测试并不重要。要正确地测试单例类,需要将其视为实例对象。为此,在安装期间将单例对象包装在一个匿名类中。每次调用setup时,你会得到一个未受影响的参与者副本:

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

#2


2  

Call i_suck_and_my_tests_are_order_dependent!() at the top of your tests when you absolutely positively need to have ordered tests. In doing so, you’re admitting that you suck and your tests are weak.

当您绝对需要进行有序测试时,请在测试的顶部调用i_suck_and_my_tests_are_order_dependent!()。这样做,你就承认自己很差劲,你的考试也很差。

...I promise I didn't write this method or the docs.

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

For more info, see: 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

有关更多信息,请参见: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