0

在使用 minitest 测试我的产品之前,我是 mocha gem 的新手。然后我遇到了一种情况,我的应用程序正在向 facebook 发布工作。它选择一些工作,然后在 facebook 上发布它们。所以有人告诉我使用模拟,我发现了 mocha gem。我看到一个样本测试。

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

但我不明白。在我的作业控制器中,我进行了验证,并且无法成功保存空作业。但是在这里模拟上面的测试断言可以在没有必填字段的情况下保存作业。那么我们在上面的测试用例中究竟测试了什么?

4

1 回答 1

1

这是一个很好的做法,通常有几个原因:

从隔离的角度来看:控制器的职责是处理传入的请求并相应地触发动作。在我们给定的案例中,操作是:创建一个新工作,如果一切正常,则向 Facebook 发布一个新帖子。(请注意我们的控制器不需要知道如何发布到 FB)

所以想象以下控制器动作:

def create
  job = Job.new job_params

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

我会像这样测试它:

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

另一个优点是:FacebookService.post_job可能需要大量时间,并且可能需要访问 Internet 等,我们不希望我们的测试在这些上挂起,特别是如果我们有 CI。

最后,我会在 FacebookService 测试中测试真正的 FB 发布,并且可能会删除一些其他方法,以防止在测试运行时每次都在 FB 上发布(它需要时间、互联网、FB 帐户......)。

于 2017-03-14T16:21:55.200 回答