我试图在我的laravel控制器上运行这个功能测试。我想测试图像处理,但要这样做,我想伪造图像上传。我该怎么做呢?我在网上找到了一些例子,但似乎没有一个适合我。我有:
public function testResizeMethod()
{
$this->prepareCleanDB();
$this->_createAccessableCompany();
$local_file = __DIR__ . '/test-files/large-avatar.jpg';
$uploadedFile = new Symfony'Component'HttpFoundation'File'UploadedFile(
$local_file,
'large-avatar.jpg',
'image/jpeg',
null,
null,
true
);
$values = array(
'company_id' => $this->company->id
);
$response = $this->action(
'POST',
'FileStorageController@store',
$values,
['file' => $uploadedFile]
);
$readable_response = $this->getReadableResponseObject($response);
}
但是控制器没有通过这个检查:
elseif (!Input::hasFile('file'))
{
return Response::error('No file uploaded');
}
所以不知何故,文件没有正确传递。我该怎么做呢?
对于遇到这个问题的人,现在可以这样做:
$response = $this->postJson('/product-import', [
'file' => new 'Illuminate'Http'UploadedFile(resource_path('test-files/large-avatar.jpg'), 'large-avatar.jpg', null, null, null, true),
]);
更新在Laravel 6中,'Illuminate'Http'UploadedFile
类的构造函数有5个参数而不是6个。这是新的构造函数:
/**
* @param string $path The full temporary path to the file
* @param string $originalName The original file name of the uploaded file
* @param string|null $mimeType The type of the file as provided by PHP; null defaults to application/octet-stream
* @param int|null $error The error constant of the upload (one of PHP's UPLOAD_ERR_XXX constants); null defaults to UPLOAD_ERR_OK
* @param bool $test Whether the test mode is active
* Local files are used in test mode hence the code should not enforce HTTP uploads
*
* @throws FileException If file_uploads is disabled
* @throws FileNotFoundException If the file does not exist
*/
public function __construct(string $path, string $originalName, string $mimeType = null, int $error = null, $test = false)
{
// ...
}
所以上面的解决方案变得简单:
$response = $this->postJson('/product-import', [
'file' => new 'Illuminate'Http'UploadedFile(resource_path('test-files/large-avatar.jpg'), 'large-avatar.jpg', null, null, true),
]);
Docs for CrawlerTrait.html#method_action reads:
所以我认为正确的调用应该是
参数字符串$方法
字符串$行动
数组$通配符
参数数组$
数组$饼干
数组$文件
数组$服务器
字符串$content
$response = $this->action(
'POST',
'FileStorageController@store',
[],
$values,
[],
['file' => $uploadedFile]
);
最好和最简单的方法:首先导入必要的东西
use Illuminate'Http'UploadedFile;
use Illuminate'Support'Facades'Storage;
然后制作一个假文件上传。
Storage::fake('local');
$file = UploadedFile::fake()->create('file.pdf');
然后制作一个JSON Data来传递文件。示例
$parameters =[
'institute'=>'Allen Peter Institute',
'total_marks'=>'100',
'aggregate_marks'=>'78',
'percentage'=>'78',
'year'=>'2002',
'qualification_document'=>$file,
];
然后将数据发送到您的API。
$user = User::where('email','candidate@fakemail.com')->first();
$response = $this->json('post', 'api/user', $parameters, $this->headers($user));
$response->assertStatus(200);
使用phpunit,您可以使用attach()方法将文件附加到表单上。
示例来自lumen docs:
public function testPhotoCanBeUploaded()
{
$this->visit('/upload')
->name('File Name', 'name')
->attach($absolutePathToFile, 'photo')
->press('Upload')
->see('Upload Successful!');
}
下面是一个如何使用自定义文件进行测试的完整示例。我需要它来解析具有已知格式的CSV文件,因此我的文件必须具有精确的格式和内容。如果您只需要图像或随机大小的文件,请使用$file->fake->image()或create()方法。这些都是与Laravel捆绑的。
namespace Tests'Feature;
use Tests'TestCase;
use Illuminate'Http'UploadedFile;
use Illuminate'Support'Facades'Storage;
class PanelistImportTest extends TestCase
{
/** @test */
public function user_should_be_able_to_upload_csv_file()
{
// If your route requires authenticated user
$user = Factory('App'User')->create();
$this->actingAs($user);
// Fake any disk here
Storage::fake('local');
$filePath='/tmp/randomstring.csv';
// Create file
file_put_contents($filePath, "HeaderA,HeaderB,HeaderC'n");
$this->postJson('/upload', [
'file' => new UploadedFile($filePath,'test.csv', null, null, null, true),
])->assertStatus(200);
Storage::disk('local')->assertExists('test.csv');
}
}
下面是控制器:
namespace App'Http'Controllers;
use Illuminate'Http'Request;
use App'Http'Controllers'Controller;
use Illuminate'Support'Facades'Storage;
class UploadController extends Controller
{
public function save(Request $request)
{
$file = $request->file('file');
Storage::disk('local')->putFileAs('', $file, $file->getClientOriginalName());
return response([
'message' => 'uploaded'
], 200);
}
}
将类似的setUp()
方法添加到您的测试用例中:
protected function setUp()
{
parent::setUp();
$_FILES = array(
'image' => array(
'name' => 'test.jpg',
'tmp_name' => __DIR__ . '/_files/phpunit-test.jpg',
'type' => 'image/jpeg',
'size' => 499,
'error' => 0
)
);
}
这将欺骗你的$_FILES全局,让Laravel认为有东西上传。