Я работаю над Laravel 5.7 и хочу задать вам вопрос относительно тестирования PHPUnit.
У меня есть тестовый класс, скажем, ProductControllerTest.php, с двумя методами testProductSoftDelete() и testProductPermanentlyDelete(). Я хочу использовать аннотацию @depends в testProductPermanentlyDelete (), чтобы сначала выполнить мягкое удаление продукта, а затем получить идентификатор продукта и перейти к тесту на окончательное удаление. Проблема здесь в том, что черта DatabaseTransaction запускает транзакции при каждом выполнении теста (метода). Мне нужно начать транзакцию перед всеми тестами моего класса ProductControllerTest, а затем откатить транзакцию в конце всех тестов. У тебя есть идеи? Из того, что я искал в Интернете, ничего не работало должным образом.
public function testProductSoftDelete()
{
some code
return $product_id;
}
/**
* @depends testProductSoftDelete
*/
public function testProductPermanentlyDelete($product_id)
{
code to test permanently deletion of the product with id $product_id.
There is a business logic behind that needs to soft delete first a
product before you permanently delete it.
}
Имеет ли смысл следующее?
namespace Tests\App\Controllers\Product;
use Tests\DatabaseTestCase;
use Tests\TestRequestsTrait;
/**
* @group Coverage
* @group App.Controllers
* @group App.Controllers.Product
*
* Class ProductControllerTest
*
* @package Tests\App\Controllers\Product
*/
class ProductControllerTest extends DatabaseTestCase
{
use TestRequestsTrait;
public function testSoftDelete()
{
$response = $this->doProductSoftDelete('9171448');
$response
->assertStatus(200)
->assertSeeText('Product sof-deleted successfully');
}
public function testUnlink()
{
$this->doProductSoftDelete('9171448');
$response = $this->actingAsSuperAdmin()->delete('/pages/admin/management/product/unlink/9171448');
$response
->assertStatus(200)
->assertSeeText('Product unlinked successfully');
}
}
namespace Tests;
trait TestRequestsTrait
{
/**
* Returns the response
*
* @param $product_id
* @return \Illuminate\Foundation\Testing\TestResponse
*/
protected function doProductSoftDelete($product_id)
{
$response = $this->actingAsSuperAdmin()->delete('/pages/admin/management/product/soft-delete/'.$product_id);
return $response;
}
}
namespace Tests;
use Illuminate\Foundation\Testing\DatabaseTransactions;
abstract class DatabaseTestCase extends TestCase
{
use CreatesApplication;
use DatabaseTransactions;
}






Создайте отдельную функцию, чтобы дважды выполнить одно и то же поведение:
public function testProductSoftDelete()
{
doSoftDelete();
}
public function testProductPermanentlyDelete()
{
doSoftDelete();
doPermanentDelete();
}
Ваш случай не является случаем тестовой зависимости, но что вы действительно хотите сделать, так это проверить, может ли программно удаленное удаление быть окончательно удалено (или что-то в этом роде). В этом случае создание зависимости увеличит сложность теста. Обычно лучше смонтировать тестовый сценарий с нуля (данные / объекты), затем выполнить логику, а затем проверить, является ли реальный сценарий ожидаемым.
Другое решение - не использовать свойство DatabaseTransaction в этом файле, а очистить его всякий раз, когда вам нужно. Если вы используете какой-либо BaseClass, например TestCase, вам нужно удалить оттуда и добавить в каждый используемый вами класс.
Или вы можете унаследовать от некоторого класса, который использует черту DatabaseTransaction, а в этом классе вы этого не сделаете. Но код вы усложняете.
При таком подходе я дважды выполню тестовый код doSoftDelete (), чего мне следует избегать. Я не знаю, смогу ли я выполнять зависимые функции. Возможно, это единственное решение. Благодарю за добрый ответ.