Как использовать макет в люмен
Как использовать макет в люмен рамок? Я использую Lumen Framework. Документы люмена очень просты. Я не знаю, как использовать насмешки или фасады, чтобы издеваться над моделями. Я пробовал некоторые средства, но никто не работал. Я хочу смоделировать две точки UserModel в методе updatePassword. Пожалуйста, помогите мне.
UserModel
use Illuminate\Database\Eloquent\Model;
class UserModel extends Model {
// connection
protected $connection = 'db_user';
// table
protected $table = 'user';
// primarykey
protected $primaryKey = 'id';
}
UserLogic
class UserLogic {
public static updatePassword($id, $password) {
// find user
$user = UserModel::find($id); // mock here**************************************
if (empty($user)) {
return 'not find user';
}
// update password
$res = UserModel::where('id', $id)
->update(['password' => $password]); // mock here*****************************
if (false == $res) {
return 'update failed';
}
// re Login
$res2 = LoginModel::clearSession();
if (false == $res2) {
return false;
}
return true;
}
}
Тест phpunit 1 не работает
use Mockery;
public function testUpdatePassword() {
$mock = Mockery:mock('db_user');
$mock->shouldReceive('find')->andReturn(false);
$res = UserLogic::updatePassword(1, '123456');
$this->assertEquals('not find user', $res);
}
тест phpunit 2
// BadMethodCallException: Method Mockery_0_Illuminate_DatabaseManager::connection() does not exist on this mock object
use Illuminate\Support\Facades\DB;
public function testUpdatePassword() {
DB::shouldReceive('select')->andReturnNull();
$res = UserLogic::updatePassword(1, '123456');
$this->assertEquals('not find user', $res);
}
Тест phpunit 3 не работает
use Mockery;
public function testUpdatePassword() {
$mock = Mockery::mock('alias:UserModel');
$mock->shouldReceive('find')->andReturn(null);
$res = UserLogic::updatePassword(1, '123456');
$this->assertEquals('not find user', $res);
}
0 ответов
Попробуй это:
$mock = Mockery::mock('alias:\NamespacePath\To\UserModel');
$mock->shouldReceive('find')->andReturn(null);
$this->app->instance('\NamespacePath\To\UserModel', $mock);
Обратите внимание, что когда вы хотите имитировать общедоступные статические функции, вы используете ключевое слово alias
. Если вы хотите вместо этого издеваться над объектом (созданным с помощьюnew
) вы используете ключевое слово overload
вместо этого (в чем разница между перегрузкой и псевдонимом в Mockery?).
Еще одна трудность, с которой я столкнулся с макетами, заключалась в том, что они все еще использовались в других тестах, в которых я больше не хотел использовать макеты, и это привело к сбою тестов. Мнимая настойчивость связана с загрузкой классов. Это происходит один раз в глобальном масштабе и остается до завершения процесса тестирования (отсюда: https://blog.gougousis.net/mocking-static-methods-with-mockery/). Итак, что бы ни было первым (используя класс как имитацию или как реальную вещь), будет определяться способ вызова класса, и после этого вы больше не сможете его изменить. В сообщении в блоге, которое я связал несколькими строками ранее, Александрос Гугусис рассказывает о том, как обойти эту проблему, запустив имитационные тесты в своих собственных процессах и отключив сохранение глобального состояния. Я попробовал его подход, но у меня были некоторые проблемы, но я тоже не тратил на это много времени. Почему нет? Потому что я нашел другое решение: вphpunit.xml
установить переменную processIsolation="true"
. Это решило проблему. Я должен отметить, что это увеличило продолжительность каждого теста примерно на. 0,5 с, поэтому подход Александроса может быть более эффективным, если вы запустите его, поскольку он будет запускать тесты только с макетами в своих собственных процессах.
Боковое примечание: это также работало с Lumen TestCase в качестве базового класса тестов.