【问题标题】:How to assert in MiniTest if method is sent to object that is NOT a mock?如果方法被发送到不是模拟的对象,如何在 MiniTest 中断言?
【发布时间】:2018-10-11 16:25:48
【问题描述】:
我知道我们可以使用 expect 检查方法是否发送到 Mock 对象,但是如何检查方法是否发送到不是 Mocks 的对象,而是应用程序中的实际对象?
动机:Sandi Metz 的演讲“Magic Tricks of Testing”https://www.youtube.com/watch?v=URSWYvyc42M 说对于单元测试传出命令方法调用(在她的演讲中解释),我们应该验证消息是否已发送。我正在尝试这样做,但我在 MiniTest 中发现的唯一内容是 assert_send,它有一些问题:
- 已弃用。
- 它不考虑发送到接收对象的参数值。如果我运行
assert_send([object, :method_called, 'argument 1', 'argument 2']),断言将返回 true,即使 object 期望的字符串与 'argument 1' 和 'argument 2' 不同。
我已经在互联网上搜索了 2 天的大部分时间。有人有什么想法吗?
【问题讨论】:
标签:
ruby-on-rails
ruby
unit-testing
mocking
minitest
【解决方案1】:
想出了我自己问题的答案:)
发布这个以防其他人像我一样遇到麻烦。
使用Spy gem,您可以断言方法已被调用。
来自 Ilija Eftimov 的这篇帖子 - https://ieftimov.com/test-doubles-theory-minitest-rspec
class BlogTest < Minitest::Test
def test_notification_is_sent_when_publishing
notification_service_spy = Spy.on(NotificationService, :notify_subscribers)
post = Post.new
user = User.new
blog = Blog.new(user)
blog.publish!(post)
assert notificaion_service_spy.has_been_called?
end
end
【解决方案2】:
这实际上很简单,没有任何宝石!假设您有一个服务 NotificationService(请注意这不是模拟),并且您想要断言在该服务上调用了一个方法。您可以编写如下所示的测试:
def test_notification_is_sent_when_publishing
notification_service_spy = Spy.on(NotificationService, :notify_subscribers)
post = Post.new
user = User.new
blog = Blog.new(user)
blog.publish!(post)
NotificationService.expects(:notify_subscribers)
end