Stub实例方法使用minitest在第二次调用时返回不同的值

dav*_*ler 6 ruby rspec minitest

我正在对用户的feed进行分页,并且想要模拟我正在使用的API的响应.API可以返回奇怪的结果,所以我想确保如果API返回我已经看过的项目,请停止分页.我第一次get_next_page调用该方法时使用了minitest来存根,但是我希望在第二次和第三次使用不同的值调用它时将其存根.

我应该只使用rSpec吗?新手到红宝石......

这是片段

test "crawler does not paginate if no new items in next page" do
    # 1: A, B
    # 2: B, D => D
    # 3: A => stop
    crawler = CrawlJob.new
    first_page = [
        {"id"=> "item-A"},
        {"id"=> "item-B"}
    ]
    second_page = [
        {"id"=> "item-B"},
        {"id"=> "item-D"}
    ]
    third_page = [{"id"=> "item-A"}]

    # can only stub with same second page
    # but I want to respond with third page
    # the second time get_next_page is called
    crawler.stub :get_next_page, second_page do
        items, times_paginated = crawler.paginate_feed(first_page)
        assert times_paginated == 3
    end
end
Run Code Online (Sandbox Code Playgroud)

Ant*_*ony 6

我确定您现在已经知道了,但是...

我必须使用mocha的模拟框架才能使其正常工作。

然后,我能够做到这一点:

 Object.any_instance.stubs(:get_value).returns('a','b').then.returns('c')
Run Code Online (Sandbox Code Playgroud)


tsa*_*amb 6

尝试向您的存根提供 proc 或 lambda 而不是值,例如

return_values = ["returned first", "returned second", "returned third"]
some_object.stub :method_to_stub, proc { return_values.shift }
Run Code Online (Sandbox Code Playgroud)

检查Minitest 的源代码后,该stub方法采用一个值或一个可调用对象作为第二个参数。

您可以通过使用 proc 或 lambda 从预定义的返回值数组中移动(或弹出)值来利用此行为。

因此,就您而言,您可以:

  1. second_page将已经定义的变量包装third_page在一个数组中,然后
  2. 传递一个 lambda 作为#stub的第二个参数,每次调用存根方法时都会破坏性地删除并返回数组的第一个元素。

例子:

return_values = [second_page, third_page]
crawler.stub :get_next_page, ->{ return_values.shift } do
    items, times_paginated = crawler.paginate_feed(first_page)
    assert times_paginated == 3
end
Run Code Online (Sandbox Code Playgroud)


zet*_*tic 3

我不了解 Minitest,但 RSpec 能够通过在and_return.

allow(crawler).to receive(:get_next_page).and_return(first_page, second_page, third_page)
Run Code Online (Sandbox Code Playgroud)