【问题标题】:How to spec a private method如何指定私有方法
【发布时间】:2010-11-11 12:32:11
【问题描述】:

我有一个带有私有方法的模型,我想用 RSpec 来指定,
你平时是怎么做的? 你只测试调用私有方法的方法吗?
还是指定私人的?如果是这样,你怎么办?

【问题讨论】:

    标签: ruby-on-rails rspec


    【解决方案1】:

    我总是采用这种方法:我想测试我的班级公开的公共 API。

    如果您有私有方法,则只能从公开给其他类的公共方法中调用它们。因此,如果您测试这些公共方法在所有条件下都按预期工作,那么您也证明了它们使用的私有方法也能正常工作。

    我承认我遇到过一些特别复杂的私有方法。在那种极端情况下,你想测试它们,你可以这样做:

    @obj.send(:private_method)
    

    【讨论】:

    • 感谢您的帮助,我同意测试公共方法证明私有方法也有效。话虽如此,我真的很想测试私有方法,您的解决方案就像一个魅力,谢谢!
    • 这是另一个有趣的方法kailuowang.blogspot.com/2010/08/…
    • 我的模型中有一个 before_save 挂钩,它通过私有 'make_private_token' 方法将私有令牌保存到数据库中。 'make_private_token' 方法使用公共类方法,而不是相反,所以我可以测试它的唯一方法是使用 send 方法。没有看到任何关于那个的extreme...
    • 如果方法需要一些参数,那么 args 呢?我会试试@obj.send(:private_method, arg1, arg2)
    • 我意识到这个答案已经很老了,但我不认为证明公共方法有效意味着他们调用的私有方法有效。两个地方的不正确逻辑碰巧相互抵消,难道不会出现误报吗?这是一个示例:pastebin.com/Zydk9e6W
    【解决方案2】:

    对于需要代码覆盖(临时或永久)的私有方法,使用rspec-context-private gem 在上下文中临时公开私有方法。

    gem 'rspec-context-private'
    

    它通过向您的项目添加共享上下文来工作。

    RSpec.shared_context 'private', private: true do
    
      before :all do
        described_class.class_eval do
          @original_private_instance_methods = private_instance_methods
          public *@original_private_instance_methods
        end
      end
    
      after :all do
        described_class.class_eval do
          private *@original_private_instance_methods
        end
      end
    
    end
    

    然后,如果您将 :private 作为元数据传递给 describe 块,则私有方法将在该上下文中公开。

    class Example
      private def foo
        'bar'
      end
    end
    
    describe Example, :private do
      it 'can test private methods' do
        expect(subject.foo).not eq 'bar'
      end
    end
    

    【讨论】:

    • 我不知道你是否再维护这个 gem,但是你的文档没有关于声明 shared_context 的代码块。所以我无法仅仅通过阅读文档来让它工作。添加此块后,它按预期工作。
    【解决方案3】:

    如果您想测试对私有方法的期望,则接受的答案不会真正起作用(至少我不知道,所以我愿意在这一点上进行更正)。相反,我所做的更加肮脏 - 在测试本身中,只需通过重新定义方法来公开方法:

    def object_to_test.my_private_method
      super
    end
    

    适用于 Ruby 1.8,无法评论任何较新的运行时。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-01
      • 1970-01-01
      相关资源
      最近更新 更多