can*_*cue 2 ruby tdd ruby-on-rails mocking minitest
有两个类,UserDevice(<ActiveRecord :: Base)和NotificationAdapter。
在NotificationAdapter中,我使用AWS SDK,而UserDevice使用NotificationAdapter实例。
联合点在下面,
protected def notificationAdapter
@notificationAdapter ||= NotificationAdapter.new(self)
end
Run Code Online (Sandbox Code Playgroud)
在UserDevice测试中,我想制作临时NotificationAdapter模拟以替换原始的NotificationAdapter,并仅在测试中使用此模拟。
但是我不知道该怎么办,因为这是我在测试中使用模拟的第一种情况。
我认为这需要执行以下两个步骤,
在测试代码中创建临时NotificationAdapter类(NorificationAdapterMock)。
NotificationAdapterMock = MiniTest::Mock.new
mock.expect :setEndpoint, 'arn:testEndpoint'
mock.expect :subscribeToAnnouncement, true
将UserDevice的notificationAdapter方法更改为以下内容,
protected def notificationAdapter
@notificationAdapter ||= NotificationAdapterMock
end
但我不知道这是对还是错。我该怎么办?
你需要
mock您的NotificationAdapter,因此它不会触发网络,但会做一些安全,容易的事情旁注:请遵循ruby样式准则,方法名称和变量应使用蛇形而不是驼峰式。
因此,我们可以这样写:
require 'minitest/autorun'
class NotificationAdapter
def initialize(device)
@device = device
end
def notify
# some scary implementation, that we don't want to use in test
raise 'Boo boo!'
end
end
class UserDevice
def notification_adapter
@notification_adapter ||= NotificationAdapter.new(self)
end
def notify
notification_adapter.notify
end
end
describe UserDevice do
it 'should use NotificationAdapter for notifications' do
device = UserDevice.new
# create mock adapter, that says 'ohai!' on notify
mock_adapter = MiniTest::Mock.new
mock_adapter.expect :notify, 'ohai!'
# connect our mock, so next NoficationAdapter.new call will return our mock
# and not usual implementation
NotificationAdapter.stub :new, mock_adapter do
device.notify.must_equal 'ohai!'
end
end
end
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请参见MiniTest的有关模拟和存根的文档。
但是,我们不要在这里停下来!我建议您将业务逻辑从ActiveRecord模型移至单独的服务类。这将具有以下良好效果:
这里是:
require 'minitest/autorun'
# same adapter as above
class NotificationAdapter
def initialize(device)
@device = device
end
def notify
raise 'Boo boo!'
end
end
class UserDevice
# the logic has been moved out
end
class NotifiesUser
def self.notify(device)
adapter = NotificationAdapter.new(device)
adapter.notify
end
end
describe NotifiesUser do
it 'should use NotificationAdapter for notifications' do
# Let's mock our device since we don't need it in our test
device = MiniTest::Mock.new
# create mock adapter, that says 'ohai!' on notify
mock_adapter = MiniTest::Mock.new
mock_adapter.expect :notify, 'ohai!'
# connect our mock, so next NoficationAdapter.new call will return our mock
# and not usual implementation
NotificationAdapter.stub :new, mock_adapter do
NotifiesUser.notify(device).must_equal 'ohai!'
end
end
end
Run Code Online (Sandbox Code Playgroud)
祝你今天愉快!
PS:如果您想了解有关隔离测试,模拟技术和常规“快速测试”运动的更多信息,我强烈建议您加里·伯恩哈特(Gary Bernhardt)的destroyallsoftware.com屏幕录像。这是有偿的东西,但是非常值得。
| 归档时间: |
|
| 查看次数: |
1037 次 |
| 最近记录: |