Вы пытаетесь смоделировать статический вызов с помощью подхода для имитации вызова функции для экземпляра объекта. Насмешивать вызовы статических функций не просто, это можно сделать с помощью псевдонимов, но это не рекомендуется.
Простой подход - просто обернуть свою логику в службу и смоделировать ее.
class UserService {
public function all(): Collection {
return User::all();
}
}
Теперь смоделированный код должен выглядеть следующим образом.
$user = factory(User::class)->make();
$mock = Mockery::mock(UserService::class);
// Teoretically all method will return Eloquent Collection, but should be fine
$mock->shouldReceive('all')->andReturn(collect($user));
$this->app->instance(UserService::class, $mock);
При использовании container
и замене экземпляров очень зависит, что вы получите эти макеты с помощью container
, а не new
ключевое слово. Таким образом, контроллер должен выглядеть примерно так:
class UserController extends Controller
{
/** @var UserService **/
private $userService;
public function __construct(UserService $userService) {
// load userService from the container as the mocked instance on tests
$this->userService = $userService;
}
public function index()
{
return $this->userService->all();
}
}
Последнее замечание: я работал над несколькими проектами в качестве основного драйвера тестирования, покрытия кода и т. Д., Гораздо проще создавать тесты, имея базу данныхтам либо используйте sqlite
, либо предоставьте среду docker
, чтобы предоставить базу данных для вас. Тестирование без него - скорее препятствие, чем предоставление чего-либо значительного. Скорость имеет решающее значение в вашем подходе к тестированию, потому что его будет много, и лучше сделать это быстрее, чем пропустить его из-за нехватки времени, и насмешка над всеми вызовами БД будет трудной.