我有下一个场景:我必须为控制器写一些单元测试。在控制器中,我有所有类型的CRUD动作。问题是,在postpatchdelete的动作中,我的api正在与一个web服务通信,在那里我传递一些数据。通信是用guzzle完成的。
问题:如何避免在我调用时发生通信?当我调用一个路由时,如何避免这种通信?有没有其他的可能性来测试大厅控制器?
我假设你的微服务是一个在Laravel的服务容器中注册的类. 据我所知, 在Laravel中, 你不能对容器外的类进行模拟.
所以, 如果你没有这样做, 在服务容器中注册服务. AppServiceProvider
类中获取微服务。 并从控制器中的容器中获取微服务。详情请看这里.
在你的单元测试中,你可以根据你的需要制作一个微服务的模拟对象,并将其注入容器中(替换真实的对象),例如,在你的testcase类中使用mock方法。
$this->instance(MyMicroService::class, Mockery::mock(MyMicroService::class, function ($mock) {
// here you tell the mock object which method will be called and what to return and how many times it will be called. it's totally customizable.
$mock->shouldReceive('contactRemoteServer')->once()->andReturnTrue();
}));
如果你在你的testcase类中使用mock方法会更容易,但它做的是同样的事情。
$this->mock(MyMicroService::class, function ($mock) {
$mock->shouldReceive('contactRemoteServer')->once()->andReturnTrue();
});
请看文档 更多的例子。
NB: 如果你不知道,模拟类是一个专门为测试而创建的类,这样它就不会影响测试结果,并且可以根据测试需要进行控制。
例如,如果你想有一个案例,你的微服务会抛出一个异常,你想测试控制器的响应,你将不得不为每个单元测试创建一个mock类。
创建一个具有相同功能的示例类,但我有一个问题,如果你正在创建单元测试,你不想让guzzle工作,那么你将测试什么。
请仔细阅读文档,你会得到这个选项。
在我的建议中,你可以使用mocking。