Ruby Unit testing techniques, Mocking and Stubbing

故事扮演 提交于 2019-12-12 13:18:48

问题


I've been recruited as a SW Dev and I'm trying to get into Unit Testing with RSPEC and RR in ruby but having an hard time deciding on a specific strategy mainly because I was assigned to write unit tests to a code which is already written.

Consider the following code which is a part of a big method called method1:

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

The relevant unit test for this part of the method would've been something like:

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

But i'm running into a few questions, basically involving best practices, for example:

How can I check if DoCheck has been called from within "method1" using RR and RSPEC?

I've tried using dont_allow(Object).DoCheck but it won't work.

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

Is there any other way to conclude if "DoCheck" was called or not?


回答1:


You can use 'Partial Mocking' technique on your object under tests. This means you need to set expectation that user.method1 sends DoCheck message to the user. RSpec can set this expectation with should_receive() method. The test will fail if expectation won't be met.

Try the following code:

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

With RR this expectation may look like this:

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

Update

But be careful with usage of mock objects and partial mocks because they make your test code tightly coupled to the current behavior of the code under tests. If you are going to refactor this code in the future you will possibly get a lot of failing tests (those that use mocks). Try testing code without mocks (input-output) and use mocks only if they clearly explain intent of the class under test. When you write test with mock always ask yourself do you really need to assert that this method calls another method or what you really care is the output of the method or something else.

Hope this helps!



来源:https://stackoverflow.com/questions/8464376/ruby-unit-testing-techniques-mocking-and-stubbing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!