I want to test this function:
public function handle(Request $request, Closure $next): mixed
{
$fields = [
'address1',
'address2',
'address3',
'city',
'country',
'countryName',
'email',
'firstname',
'lastname',
'mobile',
'phone',
'postcode',
'state',
'title'
];
foreach ($fields as $field) {
if ($request->get($field) !== null) {
return $this->scaActionMiddleware->handle($request, $next);
}
}
/** @var Response $response */
$response = $next($request);
return $response;
}
Inside my unit test file, I have these functions:
/**
* @dataProvider dataProvider
*/
public function testHandleShouldBeOk(string $input, string $value): void
{
$request = $this->createMock(Request::class);
$response = $this->createMock(JsonResponse::class);
$next = (function () use ($response) {
return $response;
})(...);
$request->expects(self::any())
->method('get')
->with($input)
->willReturn($value);
$this->scaActionMiddleware->expects(self::once())
->method('handle')
->with($request, $next);
$this->scaActionUserMiddleware->handle($request, $next);
}
/**
* @return string[][]
*/
private function dataProvider(): array
{
return [
[
'address1',
'80 boulevard magenta'
],
[
'address2',
'22 rue du Commerce'
],
[
'address3',
'124 avenue des Champs'
],
[
'city',
'Paris'
],
[
'country',
'FR'
],
[
'countryName',
'France'
],
[
'email',
'[email protected]'
],
[
'firstname',
'Paul'
],
[
'lastname',
'Bar'
],
[
'mobile',
'0601589540'
],
[
'postcode',
'75010'
],
[
'state',
'state'
],
[
'address1',
'address1'
],
[
'title',
'Mr.'
]
];
}
And finally, I have these errors:
Expectation failed for method name is "get" when invoked zero or more times Parameter 0 for invocation Illuminate\Http\Request::get('address1', null): mixed does not match expected value. Failed asserting that two strings are equal. Expected :'address2' Actual :'address1'
Expectation failed for method name is "get" when invoked zero or more times Parameter 0 for invocation Illuminate\Http\Request::get('address1', null): mixed does not match expected value. Failed asserting that two strings are equal. Expected :'address3' Actual :'address1'
Etc...
I have the impression that my test function (testHandleShouldBeOk
) only considers the first array of dataProvider
.
I followed this documentation: https://phpunit.readthedocs.io/en/9.5/writing-tests-for-phpunit.html and, I also tried to set yield
in dataProvider
but, I still have the same errors.
Can you please tell me where I'm wrong?
Thank's in advance.
EDIT: Thank @Alister Bulman, I stopped using a Request mock. I use a real Request object.
It's work:
/**
* @dataProvider dataProvider
*
* @throws ConnectDbAccessException
* @throws JwtServiceException
* @throws ConfigServiceException
* @throws ScaServiceException
* @throws SerializerServiceException
*/
public function testHandleShouldBeOk(string $field, string $value, int $invoke): void
{
$request = Request::create('foo', 'POST', [$field => $value]);
$next = function () {
return $this->createMock(Response::class);
};
$this->scaActionMiddleware->expects(self::exactly($invoke))
->method('handle')
->with($request, $next);
$this->scaActionUserMiddleware->handle($request, $next);
}
/**
* @return array<int, array<int, int|string>>
*/
private function dataProvider(): array
{
return [
['address1', '80 boulevard magenta', 1],
['address2', '22 rue du Commerce', 1],
['address3', '124 avenue des Champs', 1],
['city', 'Paris', 1],
['country', 'FR', 1],
['countryName', 'France', 1],
['email', '[email protected]', 1],
['firstname', 'Paul', 1],
['lastname', 'Bar', 1],
['mobile', '0601589540', 1],
['postcode', '75010', 1],
['state', 'state', 1],
['address1', 'address1', 1],
['title', 'Mr.', 1],
['foo', '80 boulevard magenta', 0],
];
}
CodePudding user response:
You've got 14 different tests being run - one for each part of the data-provider. You are testing each one against 14x fields, and 13 of them won't be set. You can test that (setting all the fields) - or have your test work closer to how it would be expected - returning NULL for anything it doesn't know.
Using a real Request
, and not a mock may be helpful here, since it appears to return NULL for things it does not know.