I'm trying to learn how to test properly and am struggling to get my head around mocks in the scenario below. I don't seem to be able to mock a class.
The main class uses a number of component classes to build a particular activity. I can test the component on it's own and mock it correctly but when I try to integrate test within the main class it calls the real service not the mock service.
This is in a Laravel 5.5 app.
I have a base class:
class booking {
private $calEventCreator
public function __construct(CalenderEventCreator $calEventCreator) {
$this->calEventCreator = $calEventCreator;
}
}
This is then extended by another class:
class EventType extends booking {
//do stuff
}
The CalenderEventCreator relies on an external service which I want to mock.
class CalendarEventCreator {
public function __construct(ExternalService $externalService) {
$this->externalService = $externalService;
}
}
In my test I have tried to do the following:
public function test_complete_golf_booking_is_created_no_ticket()
{
$this->booking = \App::make(\App\Booking\EventType::class);
$calendarMock = \Mockery::mock(ExternalService::class);
$calendarMock->shouldReceive([
'create' => 'return value 1',
])->once();
$this->booking->handle($this->attributes, 'booking');
}
But in trying to execute the test it's clear the ExyernalService
is not using the mocked object.
I have tried re-arranging the code as follows:
$calendarMock = \Mockery::mock(Event::class);
$calendarMock->shouldReceive([
'create' => 'return value 1',
])->once();
$this->booking = \App::make(\App\Booking\EventType::class);
$this->booking->handle($this->attributes, 'booking');
}
and tried:
$this->booking = \App::make(\App\Booking\EventType::class, ['eventService'=>$calendarMock]);
But on each occassion the real service is called not the mock version
I'm learning this so apologies about fundamental errors but can someone explain how I should mock the external service correctly
答案 0 :(得分:1)
也许有更好的方法来实现这一目标,但我使用以下方法:
$calendarMock = \Mockery::mock(ExternalService::class);
$calendarMock->shouldReceive([
'create' => 'return value 1',
])->once();
$this->booking = new \App\Booking\EventType($calendarMock);
$this->booking->handle($this->attributes, 'booking');
我没有使用服务容器来解析类,而是直接调用构造函数来传递模拟服务。
<强>更新强>
寻找其他方法,我找到this answer。使用该解决方案,您的代码将如下所示:
$calendarMock = \Mockery::mock(ExternalService::class);
$calendarMock->shouldReceive([
'create' => 'return value 1',
])->once();
$this->app->instance(ExternalService::class, $mock);
$this->booking = \App::make(\App\Booking\EventType::class);
$this->booking->handle($this->attributes, 'booking');