0

I am new to mocha gem before that I am using minitest to test my product. Then I came across a situation where my application is publishing jobs to facebook. It selects some jobs and then publish them on facebook. So somebody told me to use mocking and i found mocha gem. I see a sample test.

  def test_mocking_an_instance_method_on_a_real_object
    job = Job.new
    job.expects(:save).returns(true)
    assert job.save
  end

But I did not get the idea. In my jobs controller, I have validations and the empty job cannot be saved successfully. But here with mocking the above test assert that job can be saved without mandatory fields.So what exactly we test in above test case?

Vega
  • 27,856
  • 27
  • 95
  • 103
Zia Qamar
  • 1,694
  • 1
  • 15
  • 35
  • During your test runs, you typically won't send data to Facebook. Therefore you mock the Facebook call. If your `Job` has a method `notify_facebook` you would call `job.stubs(:notify_facebook)` before starting the `job`. – sschmeck Mar 14 '17 at 08:49

1 Answers1

1

It is a good practice generally for several reasons:

From an isolation point of view: The responsibility of the controller is to handle the incoming request and trigger actions accordingly. In our given case the actions are: create a new Job, and issue a new post to Facebook if everything fits. (Please notice our controller doesn't need to know about how to post to FB)

So imagine the following controller action:

def create
  job = Job.new job_params

  if job.save
    FacebookService.post_job job
    ...
  else
    ...
  end
end

I would test it like:

class JobsControllerTest < ActionController::TestCase
  test "should create a job and issue new FB post" do
    job_params = { title: "Job title" }

    # We expect the post_job method will be called on the FacebookService class or module, and we replace the original implementation with an 'empty/mock' method that does nothing
    FacebookService.expects :post_job

    post :create, job_params

    assert_equal(Job.count, 1) # or similar
    assert_response :created
  end
end

The other advantage is: FacebookService.post_job might take significant time, and might require internet access etc, we don't want our tests to pending on those, especially if we have CI.

And finally I would test the real FB posting in the FacebookService test, and maybe stub out some other method, to prevent posting on FB every single time when the test runs (it needs time, internet, FB account...).

Peter Toth
  • 974
  • 9
  • 9