如何在 MiniTest 中存根?
在我的测试中,我想为类的任何实例存根预设响应。
它可能看起来像这样:
Book.stubs(:title).any_instance().returns("War and Peace")
然后每当我调用 @book.title
时,它都会返回“战争与和平”。
有没有办法在 MiniTest 中做到这一点? 如果是,您能给我一个示例代码片段吗?
或者我需要摩卡之类的东西吗?
MiniTest 确实支持 Mocks,但 Mocks 对于我的需要来说太过分了。
Within my test I want to stub a canned response for any instance of a class.
It might look like something like:
Book.stubs(:title).any_instance().returns("War and Peace")
Then whenever I call @book.title
it returns "War and Peace".
Is there a way to do this within MiniTest?
If yes, can you give me an example code snippet?
Or do I need something like mocha?
MiniTest does support Mocks but Mocks are overkill for what I need.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
我使用 minitest 进行所有 Gems 测试,但使用 mocha 进行所有存根,也许可以使用 Mocks 在 minitest 中完成所有操作(没有存根或其他任何东西,但模拟非常强大),但我发现 mocha 做了干得好,如果有帮助的话:
I use minitest for all my Gems testing, but do all my stubs with mocha, it might be possible to do all in minitest with Mocks(there is no stubs or anything else, but mocks are pretty powerful), but I find mocha does a great job, if it helps:
如果您对没有模拟库的简单存根感兴趣,那么在 Ruby 中执行此操作很容易:
如果您想要更复杂的操作,例如存根类的所有实例,那么它也很容易做到,您只需要发挥一点创意:
If you're interesting in simple stubbing without a mocking library, then it's easy enough to do this in Ruby:
If you want something more complicated like stubbing all instances of a class, then it is also easy enough to do, you just have to get a little creative:
您可以轻松地在
MiniTest
中存根类方法。该信息可在 github 获取。因此,按照您的示例,并使用
Minitest::Spec
样式,这就是您应该存根方法的方式:这是一个非常愚蠢的示例,但至少为您提供了如何做您想做的事情的线索做。我使用 MiniTest v2.5.1 进行了尝试,这是 Ruby 1.9 附带的捆绑版本,似乎在此版本中尚未支持 #stub 方法,但随后我尝试使用 MiniTest v3.0,它的效果非常好。
祝您好运并祝贺您使用 MiniTest!
编辑:还有另一种方法,尽管它看起来有点黑客,但它仍然是您问题的解决方案:
You can easily stub class methods in
MiniTest
. The information is available at github.So, following your example, and using the
Minitest::Spec
style, this is how you should stub methods:This a really stupid example but at least gives you a clue on how to do what you want to do. I tried this using MiniTest v2.5.1 which is the bundled version that comes with Ruby 1.9 and it seems like in this version the #stub method was not yet supported, but then I tried with MiniTest v3.0 and it worked like a charm.
Good luck and congratulations on using MiniTest!
Edit: There is also another approach for this, and even though it seems a little bit hackish, it is still a solution to your problem:
为了进一步解释 @panic 的答案,我们假设您有一个 Book 类:
首先,创建一个 Book 实例存根,然后使它返回您想要的标题(任意次数):
然后,使 Book 类实例化您的 Book 实例存根(仅且始终在以下代码块内):
在该代码块内(仅),
Book::new
方法已被存根。让我们尝试一下:或者,最简洁的是:
或者,您可以安装 Minitest 扩展 gem
minitest-stub_any_instance
。 (注意:使用此方法时,Book#title
方法在存根之前必须存在。)现在,您可以更简单地说:如果您想验证
Book#title
code> 被调用一定次数,然后执行以下操作:因此,对于任何特定实例,调用存根方法的次数超过指定次数会引发
MockExpectationError: No more Expects available
。此外,对于任何特定实例,调用存根方法的次数少于指定的次数会引发
MockExpectationError:预期的 title()
,但前提是您在该实例上调用#verify
观点。Just to further explicate @panic's answer, let's assume you have a Book class:
First, create a Book instance stub, and make it return your desired title (any number of times):
Then, make the Book class instantiate your Book instance stub (only and always, within the following code block):
Within this code block (only), the
Book::new
method is stubbed. Let's try it:Or, most tersely:
Alternatively, you can install the Minitest extension gem
minitest-stub_any_instance
. (Note: when using this approach, theBook#title
method must exist before you stub it.) Now, you can say more simply:If you want to verify that
Book#title
is invoked a certain number of times, then do:Thus, for any particular instance, invoking the stubbed method more times than specified raises
MockExpectationError: No more expects available
.Also, for any particular instance, having invoked the stubbed method fewer times than specified raises
MockExpectationError: expected title()
, but only if you invoke#verify
on that instance at that point.您无法对类的所有实例进行存根,但可以对给定对象的任何实例方法进行存根,如下所示:
You cannot stub all instances of a class, but you can stub any instance method of a given object like this:
您始终可以在测试代码中创建一个模块,并使用包含或扩展来使用它来猴子修补类或对象。例如(在 book_test.rb 中)
现在您可以在测试中使用它
这允许您将比简单存根可能允许的更复杂的行为组合在一起
You can always create a module in your test code, and use include or extend to monkey-patch classes or objects with it. eg (in book_test.rb)
Now you can use it in your tests
This allows you to put together more complex behaviours than a simple stub might allow
我想我应该分享一个基于此处答案的示例。
我需要在一长串方法的末尾存根一个方法。这一切都始于 PayPal API 包装器的新实例。我需要存根的调用本质上是:
我创建了一个返回自身的类,除非该方法是
amount
:然后我将其存根到
PayPal::API
:您可以通过创建哈希并返回 hash.key?(method) ,这不仅仅适用于一种方法?哈希[方法]:自身。
I thought I'd share an example that I built upon the answers here.
I needed to stub a method at the end of a long chain of methods. It all started with a new instance of a PayPal API wrapper. The call I needed to stub was essentially:
I created a class that returned itself unless the method was
amount
:Then I stubbed it in to
PayPal::API
:You could make this work for more than just one method by making a hash and returning
hash.key?(method) ? hash[method] : self
.有一个 Minitest 扩展可以做到这一点。
gem 安装 minitest-stub_any_instance
There's a Minitest extension to do precicely this.
gem install minitest-stub_any_instance