繁体   English   中英

如何在我的rails minitest中使用模拟?

[英]How can I use mock in my rails minitest?

有两个类,UserDevice(<ActiveRecord :: Base)和NotificationAdapter。
在NotificationAdapter中,我使用AWS SDK,而UserDevice使用NotificationAdapter实例。
联合点在下面,

protected def notificationAdapter
  @notificationAdapter ||= NotificationAdapter.new(self)
end

在UserDevice测试中,我想制作临时NotificationAdapter模拟以替换原始的NotificationAdapter,并仅在测试中使用此模拟。
但是我不知道该怎么办,因为这是我在测试中使用模拟的第一种情况。

我认为这需要执行以下两个步骤,

  1. 在测试代​​码中创建临时NotificationAdapter类(NorificationAdapterMock)。

    NotificationAdapterMock = MiniTest::Mock.new mock.expect :setEndpoint, 'arn:testEndpoint' mock.expect :subscribeToAnnouncement, true

  2. 将UserDevice的notificationAdapter方法更改为以下内容,

    protected def notificationAdapter @notificationAdapter ||= NotificationAdapterMock end

但我不知道这是对还是错。 我该怎么办?

你需要

  1. mock您的NotificationAdapter ,因此它不会触发网络,但是会做一些安全,容易的事情
  2. 还要确保适配器正确接线

旁注:请遵循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

有关更多信息,请参见MiniTest的有关模拟存根的文档。

但是,我们不要在这里停下来! 我建议您将业务逻辑从ActiveRecord模型移到单独的服务类。 这将具有以下良好效果:

  1. 您的模型变薄
  2. 功能被很好地封装在其自己的类中,并且现在遵循“单一责任原则”
  3. 您的测试变得非常快,因为您不需要加载Rails并可以模拟您的模型。

这里是:

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

祝你今天愉快!

PS:如果您想了解有关隔离测试,模拟技术和常规“快速轨测试”运动的更多信息,我强烈建议您加里·伯恩哈特(Gary Bernhardt)的destroyallsoftware.com屏幕录像。 这是有偿的东西,但是非常值得。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM