Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby单元测试技术、模拟和存根_Ruby_Unit Testing_Rspec_Mocking_Rr - Fatal编程技术网

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

Ruby单元测试技术、模拟和存根,ruby,unit-testing,rspec,mocking,rr,Ruby,Unit Testing,Rspec,Mocking,Rr,我被招为一名软件开发人员,我正试图使用ruby中的RSPEC和RR进行单元测试,但很难决定具体的策略,主要是因为我被指派为为已经编写的代码编写单元测试 考虑以下代码,它是名为method1的大方法的一部分: if (["5234541252", "6236253223"].include?(self.id)) self.DoCheck logs.add 'Doing check', "id = #{self.id}" return end 这部分方法的相关单元测

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

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

  if (["5234541252", "6236253223"].include?(self.id))
    self.DoCheck
    logs.add 'Doing check', "id = #{self.id}"
    return
  end
这部分方法的相关单元测试如下:

“仅当id=5234541252或6236253223时才应进行检查”

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

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

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

您可以在测试对象上使用“部分模拟”技术。这意味着您需要设置
user.method1
用户发送
DoCheck
消息的期望值。RSpec可以使用
should\u 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
有了这样的期望,情况可能如下:

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(输入-输出)的情况下测试代码,并且只有当mock清楚地解释了被测试类的意图时,才使用mock。当您使用mock编写测试时,始终要问自己,您是否真的需要断言此方法调用另一个方法,或者您真正关心的是该方法的输出或其他内容


希望这有帮助

事实上,这是“大方法的一部分”,这是一个巨大的危险信号。为了更好、更简单、更有效的测试,需要对代码进行重构。此外,我还怀疑许多其他问题,比如使用带有InitialCaps的方法名。我完全同意,但不幸的是,目前无法重构代码。什么???如果他们不愿意改进代码,他们到底想要单元测试做什么?据我所知,原因是当他们决定更改某些实现时,测试仍然是有效的。因此,先编写测试,然后重构。不要跳过最后一步。:)非常感谢你的提示,我一直都在记着它,但不幸的是,我不能想出另一个非模拟测试,它将suffice@MikeyS.,然后用mock编写测试:)您现在所需要的就是在测试中获得更多的实践。有了一些经验,您将看到测试现有类的更好方法。还有一本关于如何为现有代码编写测试的好书:。再次感谢您提供的信息。。。我注意到的另一件事是,我必须使用user.save!为了使if语句的计算结果为“true”(用户显然继承自ActiveRecord::Base),我不明白为什么,我创建的用户实例位于内存中还不够吗?