使用RSpec测试实例化服务类的操作类

时间:2017-12-22 19:26:44

标签: ruby-on-rails ruby unit-testing rspec

我正在使用基于操作/服务的体系结构,其中服务类承载HTTP调用和操作类清理/打包数据并调用服务类以与外部API通信。设置工作正常,但我想知道如何为动作类设置模拟。以下是一个示例动作/服务对:

# Service
class UserService
  def update_user user_id, data
    # make request
  end
end

# Action
class UserUpdate
  def initialize user_id, user_data
    @id = user_id
    @sanitized_data = user_data
  end

  def call
    service = UserService.new
    service.call(@id, @sanitized_data)
  end
end

我可以毫无问题地模拟操作,但是当我尝试使用类或实例double作为服务时,我会收到错误。到目前为止,这是我的测试:

it "should create an instance of Agent Service" do
  agent_action_mock = class_double("AgentUpdate")
  agent_service_mock = class_double("AgentService")

  allow(agent_update_mock).to receive_message_chain(:new, :call)
  allow_any_instance_of(AgentService).to receive_message_chain(:initialize, :update_user)

  agenta_action_mock.new(99, { status: "Verified" }).call
  expect_any_instance_of(AgentService).to receive(:initialize)
end

哪个网络我Failure/Error: DEFAULT_FAILURE_NOTIFIER = lambda { |failure, _opts| raise failure } Exactly one instance should have received the following message(s) but didn't: initialize

我想知道的是如何测试该操作是否正在创建服务类的实例并调用它的方法?

1 个答案:

答案 0 :(得分:0)

我看到你的测试有几个问题。 首先,您在模拟上调用方法。除非你为call_original设置一个方法,否则double的所有方法都是stubed并且什么都不做。所以没有办法调用双重方法来触发实际行为。

其次,由于您在测试结束时使用期望,因此您应该使用期望的间谍形式 - have_received。否则它会在设置期望之后查找调用:initialize,这种情况从未发生过。