测试Laravel Controller的try catch

时间:2019-03-15 02:52:17

标签: laravel testing mocking automated-tests mockery

我正在使用Laravel 5.7并拥有此控制器

Storage

我正在尝试创建一个进入捕获的测试,但是我无法使其正常工作。

我已经尝试过模拟disk并期望方法putAnyJob被调用,但是它总是抱怨其他方法被调用而不是期望的。

我还尝试了多种模拟AnyModel$this->post的方法,但这似乎并不影响public function testUploadException() { $xlsxFile = UploadedFile::fake()->create('test.xlsx', 100); // ignore Storage and Job real work \Illuminate\Support\Facades\Storage::fake(); $this->withoutJobs(); $mock = Mockery::mock('\App\AnyModel'); $mock ->shouldReceive('create')->times(3) ->andThrow(new \Exception('any error')); $this->app->instance('\App\AnyModel', $mock); $response = $this ->withHeaders(['content-type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']) ->post('/api/upload', [$xlsxFile]); $response ->assertStatus(500) ->assertJson([ 'error' => 'Could not save file or queue not found.' ]); } 的请求。

这是我现在的测试方法:

root@3e5d84a4db42:/application/api# vendor/bin/phpunit 
PHPUnit 7.5.4 by Sebastian Bergmann and contributors.

....F                                                               5 / 5 (100%)

Time: 2.62 seconds, Memory: 20.00MB

There was 1 failure:

1) Tests\Feature\UploadTest::testUploadException
Expected status code 500 but received 200.
Failed asserting that false is true.

/application/api/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestResponse.php:133
/application/api/tests/Feature/UploadTest.php:50

FAILURES!
Tests: 5, Assertions: 8, Failures: 1.

它返回什么

 from random import randint, expovariate

2 个答案:

答案 0 :(得分:1)

这行不通的主要原因是因为您没有从IoC解析模型,例如使用app()或依赖项注入。这将适用于立面,但不适用于Eloquent模型。

您可以将控制器方法定义更改为以下内容,以从容器中解析类:

public function upload(Request $request, AnyModel $anyModel)

那么您打给create的电话是:

$anyModel->create([
    'job_id'  => $fileName
]);

测试中还存在一些问题:

  1. 该类的完全限定名称为'App\AnyModel'而不是'\App\AnyModel'。我建议使用::class而不是使用字符串,即AnyModel::class(确保已导入该类)。
  2. 您似乎只打过一次create(),因此拥有->times(3)会引发错误。

答案 1 :(得分:0)

除了使用@RossWilson所说的IoC之外,我还发现我可以通过使用

Storage::shouldReceive('disk')->andThrow('error');