Путаница по поводу повторного использования макета в phpunitPhp

Кемеровские программисты php общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Путаница по поводу повторного использования макета в phpunit

Сообщение Anonymous »

Я пишу несколько модульных тестов и застрял в том, что сначала считал ошибкой, но после большого разочарования кажется, что это было запланировано (но невозможно найти документацию/упоминание о) поведении/использовании.
Минимальный примерный случай выглядит так:
class UpdateListener()
{
public function handleStatusChange(UpdateUpdated $event): void
{
//checks various conditions of $event and modifies $successful_update_at
}
}

class CandidateTest extends TestCase
{
public function testSuccessfulUpdateTimestampManagement(): void
{
$updateListener = new UpdateListener();

//The first test verifies that a new timestamp is set
//when creating a mock with second argument set "true"
$updateEvent = $this->mockUpdateEvent(UpdateEvent::class, true);
$updateListener->handleStatusChange($updateEvent);
$this->assertEquals('2024-05-19', $candidate->successful_update_at->format('Y-m-d'));

//The second test sets "false" on the second argument and expects null on the attribute
$updateEvent = $this->mockUpdateEvent(UpdateEvent::class, false);
$updateListener->handleStatusChange($updateEvent);
$this->assertNull($candidate->successful_update_at);
}

private function mockUpdateEvent(string $class, bool $findsPreviousUpdate): UpdateEvent
{
$mockUpdate = \Mockery::mock(Update::class);
$mockUpdate->makePartial();

$previousSuccessfulUpdate = new Update();
$previousSuccessfulUpdate->register_date = '2024-05-19';

$mockQueryBuilder = \Mockery::mock(Builder::class);
$mockQueryBuilder->shouldReceive('getResult')->andReturn(
$findsPreviousUpdate ? $previousSuccessfulUpdate : null
);
$mockUpdate->shouldReceive('query')->andReturn($mockQueryBuilder);

return new $class($mockUpdate);
}
}

Итак, в этом минимальном примере происходит то, что я (или мне так казалось) создаю чистые макеты класса, который использует построитель запросов (laravel 11, если это имеет какое-либо значение). ), чтобы «найти» объект при определенных условиях и использовать временную метку этого объекта на макете субъекта. При некоторых условиях я ожидаю возврата null и использую этот второй флаг аргумента, чтобы сообщить макету, что он должен возвращать.
Однако именно здесь мы добираемся до «Проблемы»: второе утверждение никогда не является нулевым, макет всегда возвращает $previousSuccessfulUpdate независимо от того, что я говорю ему вернуть при создании макета.
Поэтому, посмотрев на то, что делает макеты::mock и ->andReturn, становится ясно, что под капотом происходит какое-то повторное использование макетных объектов и ожидание возврата. >
Как правильно выполнить такое утверждение на одном и том же имитируемом объекте, ожидая при этом разных результатов от имитируемых методов? Я упускаю что-то основное, что заставило бы это работать так, как я ожидаю? Разделение утверждений на разные тесты, чтобы получить своего рода «TearDown» для сброса моих макетов?
Поскольку ->andReturn, похоже, использует «очередь» возвращаемых ответов, я получаю ожидаемые утверждения, просто передавая ему различные ожидаемые возвращаемые значения в том порядке, в котором я их ожидаю. Это похоже на очень «жестко запрограммированный» способ сделать это и подразумевает, что я должен знать точный порядок и количество возвратов, которые, как я ожидаю, даст любой тест для любого макета. Я бы предпочел иметь возможность в любой момент времени точно указать, что именно должен возвращать макет, изменяя его всякий раз, когда я считаю нужным...?
$mockQueryBuilder->shouldReceive('getResult')->andReturn($previousSuccessfulUpdate, null);


Подробнее здесь: https://stackoverflow.com/questions/785 ... in-phpunit
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Php»