嘲笑类型模拟类时出错



我正在尝试创建一个模拟对象并将其传递给构造函数。我收到错误

Users            
✘ GetUser ItShouldThrowAnExceptionIfUserDoesNotExist
┐
├ Failed asserting that exception of type "TypeError" matches expected exception "FooExceptionsUserNotFoundException". Message was: "Argument 2 passed to FooClientsUsers::__construct() must be an instance of FooApiUsersApi, instance of Mockery_0__UsersApi given, called in /Users/tomcaflisch/myproject/tests/Clients/UsersTest.php on line 25" at
├ /Users/tomcaflisch/myproject/lib/Clients/Users.php:26                                                                                                                                                                                                                                                                                                                                     
├ /Users/tomcaflisch/myproject/tests/Clients/UsersTest.php:25                                                                                                                                                                                                                                                                                                                               
├ .                                                                                                                                                                                                                                                                                                                                                                                                                 
┴

根据文档,这应该有效。

用户类

class Users
{
public function __construct(?string $secret, UsersApi $usersApi = null)
{
}

用户测试类

use MockeryAdapterPhpunitMockeryTestCase;
class UsersTest extends MockeryTestCase
{
public function testGetUser_ItShouldThrowAnExceptionIfUserDoesNotExist()
{
$this->expectException(UserNotFoundException::class);
$this->expectExceptionMessage("User with id, email, or username foo@bar.com not found");
$usersApi = Mockery::mock('UsersApi');
$usersApi->shouldReceive('get')
->andThrow(new UserNotFoundException("User with id, email, or username foo@bar.com not found"));
$usersClient = new Users(null, $usersApi);
}

啊,我刚刚想通了。我需要使用完整的命名空间。

取代

$usersApi = Mockery::mock('UsersApi');

$usersApi = Mockery::mock('FooApiUsersApi');

我通常走这条路:

<?php
namespace TestsUnit;
use AppServicesServiceToBeMocked;
use AppServicesServiceToBeTested;
use AppJobsJobToBeTested;
use Mockery;
use MockeryMockInterface;
use TestsTestCase;
class ServiceToBeTestedTest extends TestCase
{
private ServiceToBeTested $testService;
public function testSomePartThatDoesntUseTheInjectedDependency(): void
{
/** @var ServiceToBeMocked $mockService */
$mockService = Mockery::mock(ServiceToBeMocked::class);
// now you can use it
$this->testService = new ServiceToBeTested($mockService);
// continue with testing
// assert things happened
}
public function testSomePartThatUsesTheInjectedDependency(): void
{
// The part you're testing actually uses the mocked service
// by calling its method mockedMethod, which should in this
// given test return 'a-string-value'
/** @var ServiceToBeMocked $mockService */
$mockService = Mockery::mock(ServiceToBeMocked::class, function (MockInterface $mock) {
$mock->shouldReceive('mockedMethod')
->andReturn('a-string-value');
});
// now you can use it
$this->testService = new ServiceToBeTested($mockService);
// continue with testing
// assert things happened
}
public function testSomethingThatUsesServiceToBeMockedInAJob(): void
{
// In this case we don't need to assign it to a variable
Mockery::mock(ServiceToBeMocked::class, function (MockInterface $mock) {
$mock->shouldReceive('mockedMethod')
->andReturn('a-string-value');
});
// JobToBeTested::handle(ServiceToBeMocked $mockService)
app()->call(JobToBeTested::class . '@handle);
// assert things happened
}
}

最新更新