Как я могу включить тестирование в течение действительного времени с помощью помощников проверки Laravel? - PullRequest
1 голос
/ 09 февраля 2020

Я пытаюсь написать функциональный тест, который проверяет, что предоставленное end_time не происходит перед предоставленным start_time. Я провел последние несколько дней; Я думаю, что видел все SO сообщения и все еще испытываю проблемы с получением их в моей голове.

Я смог успешно протестировать / подтвердить на основе условия:

MyTest . php

/** @test */
public function a_blackout_that_does_not_close_the_location_requires_an_end_time()
{
    $table = 'my_table';

    $blackout = factory(Blackout::class)->create([
        'closed' => 0,
    ]);

    $this->assertDatabaseHas($table, [
        'end_time' => $blackout->end_time,
    ]);
}

MyController. php

public function store(Request $request) {
    $attributes = $request->validate([
        ...
        'date' => ['required'],
        'closed' => ['nullable'],
        'start_time' => ['required_if:closed,0'],  // works great
        'end_time' => ['required_if:closed,0'],    // works great
    ]);

    $blackout = new Blackout($attributes);

    ...
}

Теперь я хочу убедиться, что любое предоставленное end_time не является перед предоставленным start_time.

MyTest. php

/** @test */
public function a_blackout_end_time_cannot_be_before_the_start_time()
{
    $blackout = factory(Blackout::class)->raw([
        'closed' => 0,
        'start_time' => '08:00:00',
        'end_time' => '07:00:00',
    ]);

    $response = $this->post('api/v1/blackouts', $blackout)
        ->assertSessionHasErrors('end_time');
}

Вот что я пытаюсь сделать:

MyController. php

    public function store(Request $request) {
    $attributes = $request->validate([
        ...
        'date' => ['required'],
        'closed' => ['nullable'],
        'start_time' => ['required_if:closed,0'],
        'end_time' => ['required_if:closed,0|after:start_time'],
    ]);

    $blackout = new Blackout($attributes);

    ...
}

В моем тесте постоянно появляется ошибка:

1) Тесты \ Feature \ BlackoutsTest :: a_blackout_end_time_cannot_be_before_the_start_time Сессия отсутствует ожидаемый ключ [ошибки]. Не удалось утверждать, что false - это правда.

Это говорит о том, что он не получает правильные ошибки, установленные / возвращенные из проверки. Я попробовал несколько способов отформатировать start_time и end_time, чтобы попытаться сравнить.

Далее в моем контроллере я могу сравнительно легко сравнивать времена:

MyController. php

...
$start_time = strtotime($blackout->start_time);
$end_time = strtotime($blackout->end_time);

if ($end_time <= $start_time) {
    // Invalid duration
} else {
    $blackout->save();
}

...

Я изо всех сил пытаюсь проверить через валидатор, чтобы я мог лучше использовать сообщения об ошибках.

Спасибо за любые предложения!

РЕДАКТИРОВАТЬ

Спасибо @ Томас Ван дер Веен. Понятно, что я учусь, просматривая примеры json, и считаю, что неправильно делаю много вещей (большой сюрприз).

Я обновил свой тест, чтобы теперь использовать postJson вместо post. Я проверяю 422 ответ и что должна быть ошибка end_time.

/** @test */
public function a_blackout_end_time_cannot_be_before_the_start_time()
{
    $blackout = factory(Blackout::class)->raw([
        'closed' => 0,
        'start_time' => '08:00:00',
        'end_time' => '07:00:00',
     ]);

     $response = $this->postJson('api/v1/blackouts', $blackout)
         ->assertStatus(422)
         ->assertJsonValidationErrors('end_time');
 }

MyController. php

$attributes = $request->validate([
   ...
   'date' => ['required'],
   'closed' => ['nullable'],
   'start_time' => ['required_if:closed,0|date|'],
   'end_time' => ['required_if:closed,0|date|after:start_time'],
]);

...

$blackout->save();

return response()->json(['data' => $blackout], 201);

Ответ теста:

1) Tests \ Feature \ BlackoutsTest :: a_blackout_end_time_cannot_be_before_the_start_time Ожидаемый код состояния 422, но получен 201. Не удалось подтвердить, что значение false равно true.

Что говорит мне моя проверка плоха, так как она проходит до 201 года.

Спасибо вам обоим за вашу помощь. Я чувствую, что начинаю говорить по кругу и делаю это намного сложнее, чем сейчас.

1 Ответ

0 голосов
/ 10 февраля 2020

Спасибо вам обоим за ваши предложения! Они оба помогли мне получить этот ответ. Хотя я считаю, что все еще пишу / выполняю тесты неправильно

Вот решение, которое я выбрал, если есть лучший способ, пожалуйста, дайте мне знать, чтобы я мог обновить свой ответ.

В итоге я написал пользовательское правило проверки и передал мой time_start для сравнения двух раз.

MyTest. php

/** @test */
public function a_blackout_end_time_cannot_be_before_the_start_time()
{
    $blackout = factory(Blackout::class)->raw([
        'closed' => 0,
        'time_start' => '08:00',
        'time_end' => '07:00',
    ]);

    $response = $this->postJson('api/v1/blackouts', $blackout)
        ->assertStatus(422)
        ->assertJsonValidationErrors('time_end');
}

MyController. php

public function store(Request $request)
{
    $attributes = $request->validate([
        ...
        'date' => ['required', new DateFormatRule], // Custom rule
        'closed' => 'nullable',
        'time_start' => 'required_if:closed,0',
        'time_end' => ['required_if:closed,0', new TimeDurationRule($request->time_start)],
    ]);

    $blackout = new Blackout($attributes);
    ...
}

TimeDurationRule. php

**
 * Create a new rule instance.
 *
 * @return void
 */
public function __construct($time_start)
{
    $this->time_start = $time_start;
}

/**
 * Determine if the validation rule passes.
 *
 * @param string $attribute
 * @param mixed $value
 * @return bool
 */
public function passes($attribute, $value)
{
    return strtotime($value) > strtotime($this->time_start);
}

/**
 * Get the validation error message.
 *
 * @return string
 */
public function message()
{
    return 'Time duration is invalid.';
}

В моем тест Я получаю 422 ответа, как и ожидалось. Я могу убедиться, что все работает, изменив имя ожидаемой ошибки с time_end на time_end123, и я получу сообщение об ошибке, сказав, что ожидал time_end, а не `time_end123.

...