Ruby单元测试技术,模拟和存根



我被招聘为一名软件开发人员,我正在尝试使用ruby中的RSPEC和RR进行单元测试,但很难决定具体的策略,主要是因为我被分配到已经编写的代码中编写单元测试。

考虑以下代码,它是名为method1的大方法的一部分:

  if (["5234541252", "6236253223"].include?(self.id))
    self.DoCheck
    logs.add 'Doing check', "id = #{self.id}"
    return
  end

方法这部分的相关单元测试应该是这样的:

"should do check only if id = 5234541252 or 6236253223"

但是我遇到了一些问题,基本上涉及到最佳实践,例如:

我如何检查DoCheck是否已经从使用RR和RSPEC的"method1"内调用?

我试过使用dont_allow(Object)。DoCheck,但是不工作

describe :do_route do
  it "should do check only if id = 5234541252 or 6236253223" do
  user = Factory(:User)
  user.id = "5234541252"
  dont_allow(user).DoCheck
  user.method1
end

是否有其他方法来判断是否调用了"DoCheck"?

您可以在测试对象上使用'Partial mock '技术。这意味着您需要设置user.method1user发送DoCheck消息的期望。RSpec可以通过should_receive()方法设置这个期望。如果不满足期望,测试将失败。

尝试以下代码:

describe :do_route do
  it "should do check if id = 5234541252 or 6236253223" do
    user = Factory(:User)
    user.id = "5234541252"
    user.should_receive(:DoCheck) # set expectation that DoCheck will be called
    user.method1  # execute
  end
end

对于RR,期望可能是这样的:

describe :do_route do
  it "should do check if id = 5234541252 or 6236253223" do
    user = Factory(:User)
    user.id = "5234541252"
    mock(user).DoCheck # set expectation that DoCheck will be called
    user.method1  # execute
  end
end
<标题> 更新

但是要小心使用模拟对象和部分模拟,因为它们使您的测试代码与测试代码的当前行为紧密耦合。如果将来要重构这些代码,可能会遇到很多失败的测试(那些使用mock的测试)。尝试在没有模拟(输入-输出)的情况下测试代码,并且只有在模拟清楚地解释了被测类的意图时才使用模拟。当您使用mock编写test时,总是要问自己是否真的需要断言这个方法调用了另一个方法,或者您真正关心的是该方法的输出或其他什么。

希望这对你有帮助!

相关内容

  • 没有找到相关文章

最新更新