How do I test (TDD) a singleton class?

﹥>﹥吖頭↗ 提交于 2019-12-24 03:24:04

问题


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.

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.

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

Thanks!


回答1:


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:

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



回答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 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



来源:https://stackoverflow.com/questions/26171007/how-do-i-test-tdd-a-singleton-class

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!