代码之家  ›  专栏  ›  技术社区  ›  brainfck

如何测试单件课程?

  •  11
  • brainfck  · 技术社区  · 15 年前

    我正在使用rspec,并希望多次测试单例类的构造函数。

    我该怎么做?

    最好的问候

    8 回复  |  直到 10 年前
        1
  •  3
  •   Nicolai Reuschling    15 年前

    看一看 http://blog.ardes.com/2006/12/11/testing-singletons-with-ruby :

    require 'singleton'
    
    class <<Singleton
      def included_with_reset(klass)
        included_without_reset(klass)
        class <<klass
          def reset_instance
            Singleton.send :__init__, self
            self
          end
        end
      end
      alias_method :included_without_reset, :included
      alias_method :included, :included_with_reset
    end
    
        2
  •  17
  •   Community CDub    7 年前

    单例类基本上是这样做的

    def self.instance
      @instance ||= new
    end
    
    private_class_method :new
    

    因此,通过使用send调用private方法new,可以完全绕过memoization。

    let(:instance) { GlobalClass.send(:new) }
    

    这种方法的一个好处是,运行测试不会修改任何全局状态。


    可能是更好的方法,从 this answer 以下内容:

    let(:instance) { Class.new(GlobalClass).instance }
    

    这将创建一个匿名类,该类继承自 GlobalClass ,其中存储了所有类级实例变量。然后在每次测试后丢弃,离开 全球级 未触及的

        3
  •  7
  •   Panic    11 年前
    # singleton_spec.rb
    require "singleton"
    
    class Global
      include Singleton
    
      def initialize
        puts "Initializing"
      end
    end
    
    describe Global do
      before do
        Singleton.__init__(Global)
      end
    
      it "test1" do
        Global.instance
      end
    
      it "test2" do
        Global.instance
      end
    end
    
    
    % rspec singleton_spec.rb -fd
    Global
    Initializing
      test1
    Initializing
      test2
    
        4
  •  3
  •   John Bachir    12 年前

    我看到的一种模式是让单例成为实际类的子类。您在生产代码中使用单例版本,但测试使用的是基本(非单例)类。

    例子:

    class MyClass
      attr_accessor :some_state
    
      def initialize
         @some_state = {}
      end
    end
    
    class MySingletonClass < MyClass
      include Singleton
    end
    

    …但我正在寻找更好的方法。

    我的部分问题是,我使用JRuBy和挂钩到Java系统首选项中, 全球的。其余的我认为我可以重构出来。

        5
  •  2
  •   Wayne Conrad    12 年前

    人们使用单件的一个原因是“全局变量是坏的,M'kay?”单例是一个全局变量,隔离在一个名称空间中,并且具有惰性的实例化。考虑一个真正的全局变量是否可以简化一些事情,特别是在不需要惰性实例化的情况下。

        6
  •  1
  •   user23743    15 年前

    将其重构为可以构造多次的类。这有一个副作用(有些人会说是有益的),即从类中删除了单例性质。

    另一种方法是:您发现需要多次调用构造函数。为什么? 应该 类只构造一个实例?单件提供什么好处?

        7
  •  0
  •   Chris Arnold    15 年前

    RSPEC是否允许您执行预测试操作?因此,可以向静态类添加另一个方法,该方法清除了构造函数期间所做的任何操作。然后,在每次测试之前就调用它。

        8
  •  -1
  •   TK.    15 年前

    你可以做一个新的 it 并为每个规范阻塞。将您的规范分解为可测试单元。使用“之前”和“之后”设置和清除您所做的任何事情。

    before(:each) after(:each) 块。