お世話になっております。
Laravelプロジェクトのユニットテストを作成しています。
テストしたいのはモデルクラスで、いくつかメソッドが書いてある状態です。
class テストしたいクラス extends Model { function テストしたいメソッド1(){ //略 } function テストしたいメソッド2(){ //略 } function テストしたいメソッド3(){ $foo = new テストしたいクラス(); $foo->save(); } }
すでに テストしたいメソッド1、テストしたいメソッド2 のテストは書いて動作確認もでき、
新しく テストしたいメソッド3 のテストメソッドを追記した際表題のエラーが出ました。
テスト用のファイルは以下の様に書いています。
class テストしたいクラスTest extends TestCase { use RefreshDatabase; private $sut; protected function setUp(): void { parent::setUp(); $this->sut = new テストしたいクラス; } /** * @test */ function テストしたいメソッド1() { $actual = $this->sut->テストしたいメソッド1(); //略 } /** * @test */ function テストしたいメソッド2() { $actual = $this->sut->テストしたいメソッド2(); //略 } /** * @test */ function テストしたいメソッド3() { $mock = \Mockery::mock('overload:テストしたいクラス'); //←ここでエラー $mock->shouldReceive('save') ->once() ->andThrow(new \Exception()); $actual = $this->sut->テストしたいメソッド3(); //ロールバックされているか確認 $this->assertDatabaseMissing('テストしたい_クラス', [ 'test' => test ]); } }
上記コード内、"//←ここでエラー"の行で
Mockery\Exception\RuntimeException: Could not load mock テストしたいクラス, class already exists
とエラーが出てしまいます。
やったこと
・すでにsetUp内で同クラスをnewしていることが原因でこのエラーが出ていると思うので、
setUpのnewをコメントアウトするとモックの作成は成功しました。
ただ、各テストケース内で毎回newしなくて良い様にsetUpに記述しているので、これは残したいです。
・アノテーションを追加
@runInSeparateProcess
@preserveGlobalState disabled
を テストしたいメソッド3 に書き足しましたが解消されませんでした。
・overload:せずにモック作成
```
$mock = \Mockery::mock(テストしたいクラス::class);
$mock->shouldReceive('save')
->once()
->andThrow(new \Exception());
のようにoverloadをせずモックを作成するとアサートの行まで進むのですが、 モックがうまくできていないのか、アサートは失敗します(saveメソッドでエラーにならずデータベースに保存されてしまう)。 setUp内で new しつつ、テストメソッド内で同クラスをモックするにはどうすれば良いでしょうか。 テストを書き始めて日が浅いため根本的にどこか間違えている可能性もあるのですが、 何かお気づきの点がありましたらアドバイスいただけますと幸いです。 よろしくお願いいたします。 ================== 環境 Laravel 6.8 PHPUnit 8.5.8 Mockery 1.0
あなたの回答
tips
プレビュー