在这种情况下我该如何编写测试?
How can I write a test in this case?
P.S.:
起初我问如何模拟 Model::create,但我想做的是编写一个测试,当 try 发生错误时,它会正确地进入 catch。
感谢@matiaslauriti 的评论,我找到了更好的方法,所以我将把我的问题从如何模拟更改为如何编写测试。
详情请看答案部分和评论。
・・・・・・・・
我有这个代码。
class MyModel extends Model
{
public static function addRecord()
{
//...
try {
DB::beginTransaction();
foreach ($rows as $row) {
self::create([
'name' => $name,
'phone' => '',
]);
}
DB::commit();
} catch (\Exception $ex) {
DB::rollback();
throw($e);
}
}
}
这是我的测试 code.but 模拟 returns 一个错误,测试不起作用。
class MyModelTest extends TestCase
{
protected function setUp(): void
{
parent::setUp();
$this->my_model = new MyModel();
}
/**
* @test
*/
public function addRecord_error()
{
$mock = \Mockery::mock(MyModel::class)->makePartial();
$mock->shouldReceive('create')
->once()
->andThrow(new \Exception());
$this->app->bind(MyModel::class, function () use ($mock) {
return $mock;
});
$my_model = app(MyModel::class);
//run method
$my_model->addRecord();
// ↑↑ This return error with
//BadMethodCallException:Static method
//Mockery_2_App_Models_MyModel::addRecord() does not exist on this mock object
//try {
//$my_model->addRecord();
//} catch (\Exception $ex) {
// $this->assertCount(0, MyModel::all());
//}
}
}
我想编写一个测试,如果尝试失败,它会进行捕获并调用回滚。
您的测试代码应如下所示:
use Exception;
use Mockery\Mockery;
class MyModelTest extends TestCase
{
/**
* @test
*/
public function addRecord_error()
{
$mock = Mockery::mock(MyModel::class)->makePartial();
$mock->shouldReceive('create')
->once()
->andThrow(new Exception);
$my_model = app(MyModel::class);
try {
$my_model::addRecord();
} catch (Exception $exception) {
$this->assertCount(0, Model::all());
}
}
}
如果您在内部使用模型,则必须将模拟添加到 Service Container before app
辅助函数:
$this->app->bind(MyModel::class, function () use ($mock) {
return $mock;
});
请记住,如果回滚,$this->assertCount(0, Model::all());
应替换为您要测试的模型。因此,将 Model
替换为所需的 Model
.
但是,那应该一直通过,因为你是第一次抛出错误 运行,所以你永远不会添加任何东西。所以assertCount
应该总是pass的,删不删都是一样的。
P.S.: 起初我问如何模拟 Model::create,但我想做的是编写一个测试,当 try 发生错误时,它会正确地进入 catch。
感谢@matiaslauriti 的评论,我找到了更好的方法,所以我将把我的问题从如何模拟更改为如何编写测试。
详情请看答案部分和评论。
・・・・・・・・
我有这个代码。
class MyModel extends Model
{
public static function addRecord()
{
//...
try {
DB::beginTransaction();
foreach ($rows as $row) {
self::create([
'name' => $name,
'phone' => '',
]);
}
DB::commit();
} catch (\Exception $ex) {
DB::rollback();
throw($e);
}
}
}
这是我的测试 code.but 模拟 returns 一个错误,测试不起作用。
class MyModelTest extends TestCase
{
protected function setUp(): void
{
parent::setUp();
$this->my_model = new MyModel();
}
/**
* @test
*/
public function addRecord_error()
{
$mock = \Mockery::mock(MyModel::class)->makePartial();
$mock->shouldReceive('create')
->once()
->andThrow(new \Exception());
$this->app->bind(MyModel::class, function () use ($mock) {
return $mock;
});
$my_model = app(MyModel::class);
//run method
$my_model->addRecord();
// ↑↑ This return error with
//BadMethodCallException:Static method
//Mockery_2_App_Models_MyModel::addRecord() does not exist on this mock object
//try {
//$my_model->addRecord();
//} catch (\Exception $ex) {
// $this->assertCount(0, MyModel::all());
//}
}
}
我想编写一个测试,如果尝试失败,它会进行捕获并调用回滚。
您的测试代码应如下所示:
use Exception;
use Mockery\Mockery;
class MyModelTest extends TestCase
{
/**
* @test
*/
public function addRecord_error()
{
$mock = Mockery::mock(MyModel::class)->makePartial();
$mock->shouldReceive('create')
->once()
->andThrow(new Exception);
$my_model = app(MyModel::class);
try {
$my_model::addRecord();
} catch (Exception $exception) {
$this->assertCount(0, Model::all());
}
}
}
如果您在内部使用模型,则必须将模拟添加到 Service Container before app
辅助函数:
$this->app->bind(MyModel::class, function () use ($mock) {
return $mock;
});
请记住,如果回滚,$this->assertCount(0, Model::all());
应替换为您要测试的模型。因此,将 Model
替换为所需的 Model
.
但是,那应该一直通过,因为你是第一次抛出错误 运行,所以你永远不会添加任何东西。所以assertCount
应该总是pass的,删不删都是一样的。