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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用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

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

答案

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

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

以上是关于使用RSpec测试实例化服务类的操作类的主要内容,如果未能解决你的问题,请参考以下文章

PHP能在类中实例化一个类吗

rspec 3 - 存根类方法

怎样判断一个类的实例是不是属于一个类对象

Spring Boot 测试:无法实例化内部配置类

java反射1--产生Class类的实例化对象三个方法

php设计模式--单例模式