我对测试很陌生,而且我已经接受了一项我不知道如何写作的测试。我的应用程序中有一条路线,它所做的只是从一些在线数据生成一个CSV文件。我需要测试以查看是否创建了该CSV文件。我怎么做。这是我的路线:
...generate data...
$strContent = "'Title', 'MediaId', 'Original File Name'". "'\n";
foreach ($objData->media_list as $objMedia) {
$strContent .= "'" . $objMedia->title . "', '" . $objMedia->media_id . "', '" . $objMedia->original_filename . "'\n";
}
/**
* Comment this line out to output file
*/
// exit;
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Type: application/force-download');
header('Content-Type: application/csv');
header('Content-Type: application/download');
header('Content-Disposition: attachment;filename=Limelight.csv');
echo $strContent;
exit;
这是我的测试:
public function testIndex()
{
$this->call('GET', '/limelight');
$this->assertFileExists('Limelight.csv');
}
测试失败,但我甚至不确定它是否是正确的测试。该文件未保存到文件系统。它直接输出到浏览器。我如何在PHPUnit中测试它?
答案 0 :(得分:1)
也许更简单的事情:
public function testCsv(){
$response = $this->call('GET', $urlToControllerThatGeneratesCsvDownload);
$this->assertTrue(strpos($response->content(), 'csv') !== false);
}
在Controller中,csv的创建方式如下:
return \Excel::create('XXXXX', function($excel) {
$excel->sheet('Sheet 1', function($sheet) {
.....
});
})->download('csv');
这对我有用
答案 1 :(得分:0)
如何使用file_get_contents()获取文件并将其转储到变量中,然后可以测量其大小,内容等:
$data = file_get_contents($url);
$this->assertTrue(strlen($data) > $someThreshold);
$this->assertTrue(preg_match('/someString/', $data));
$this->assertEquals($knownHash, md5($data));
或者,如果您想要非常彻底,可以扫描每一行以确保它是有效的CSV并包含您的期望:
$fp = fopen($url, 'r');
while (true) {
$line = fgetcsv($fp);
if (feof($fp)) {
break;
}
$this->assertTrue(is_array($line));
$this->assertTrue(count($line) === $expectedNumberOfItems);
// etc...
}
答案 2 :(得分:0)
代码中unit test
至少有两件事:
对于#1,问题是$strContent
是一个局部变量,并且没有公开。验证它的一种方法是将CSV生成代码提取到另一个方法中,并对该方法进行单元测试。
对于#2,你需要一些帮助方法/类,在代码和本机PHP代码之间使用它作为bridge
。例如:
class MyHttpResponse {
public function header($header, $replace=false, $httpCode=200) {
header($location, $replace, $httpCode);
}
public function sendBody($body) {
echo $body;
}
}
并从那里获取原始代码调用方法,而不是PHP本机代码。然后,您可以使用mocks
或fakes
来断言发送了正确的headers
和body
。断言body
响应也涵盖#1的测试,因此如果在body
上执行正确的断言,则可以跳过这些测试。
在编写计划对其进行单元测试的代码时,您要记住的一件事是,您应该尽可能多地将工作委托给其他方法/类。这不仅仅是为了unit testing
带来的好处,它还会带您进入Single Responsibility Principle。就SRP而言,您的index
方法有点不知所措,并且不应该负责从数据数组生成字符串,这应该是数据处理器类/方法的角色。