3

我被招募为 SW 开发人员,我正在尝试在 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"

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

如何检查是否已使用 RR 和 RSPEC 从“method1”中调用 DoCheck?

我试过使用 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”?

4

1 回答 1

0

您可以在被测对象上使用“部分模拟”技术。这意味着您需要设置将消息user.method1发送DoCheckuser. 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 编写测试时,总是问自己你是否真的需要断言这个方法调用了另一个方法,或者你真正关心的是方法的输出或其他东西。

希望这可以帮助!

于 2011-12-11T14:54:51.470 回答