提问人:aborted 提问时间:6/30/2016 最后编辑:aborted 更新时间:3/5/2020 访问量:2388
如何在 Laravel 5 包内的测试中模拟 Accept 标头?
How to simulate Accept header in a test within a Laravel 5 package?
问:
我目前正在构建一个 Laravel 包,该包通过宏注入了新方法。我注入的方法已经完成,预计效果很好,但我也想在发布之前对其进行测试。Illuminate\Http\Request
我的测试要求我更改请求的标头,以便查看测试是否通过。因此,我做了以下操作来模拟请求:Accept
// package/tests/TestCase.php
namespace Vendor\Package;
use Illuminate\Http\Request;
use Orchestra\Testbench\TestCase as Orchestra;
abstract class TestCase extends Orchestra
{
/**
* Holds the request
* @var Illuminate\Http\Request
*/
protected $request;
/**
* Setup the test
*/
public function setUp()
{
parent::setUp();
$this->request = Request::capture();
$this->request->headers->set('Accept', 'application/x-yaml');
}
}
然后在我的测试中,我使用我注入的方法,它总是返回 false,因为标头没有设置为 .Request
$this->request->wantsYaml()
Accept
application/x-yaml
class RequestTest extends TestCase
{
/** @test */
public function it_should_return_a_bool_if_page_wants_yaml_or_not()
{
dump($this->request->wantsYaml()); // Return false
$this->assertTrue($this->request->wantsYaml()); // It fails!
}
}
如何在 Laravel 包开发中的测试中继续模拟标头?
编辑
这是我的班级YamlRequest
use Illuminate\Http\Request;
use Illuminate\Support\Str;
class YamlRequest extends Request
{
/**
* Acceptable content type for YAML.
* @var array
*/
protected $contentTypeData = ['/x-yaml', '+x-yaml'];
/**
* Determine if the current request is asking for YAML in return.
*
* @return bool
*/
public function wantsYaml()
{
$acceptable = $this->getAcceptableContentTypes();
// If I dd($acceptable), it comes out as empty during tests!
return isset($acceptable[0]) && Str::contains($acceptable[0], $this->contentTypeData);
}
}
因此,我实际上必须模拟 Accept,以查看我的方法是否按预期工作。wantsYaml
答:
好的,老实说,我不知道您如何在代码中使用它,但我认为这里有 2 个问题:YamlRequest
1)在你的测试中,你创建的是对象而不是对象 - 这是正确的吗?对我来说似乎不是,但也许应该是这样的Illuminate\Http\Request
YamlRequest
2)第二件事是方法的代码。查看您的方法实现,您设置了无效的标头,因为方法获取标头而不是getAcceptableContentTypes()
Accept
Content-Type
如果我将测试代码更改为如下所示:
$request = new \App\Http\Requests\YamlRequest();
$request->headers->set('Accept', 'application/x-yaml');
$this->assertTrue($request->wantsYaml());
它通过了。但是我不得不使用标题而不是.我认为这是错误。Accept
Content-Type
评论
wantsYaml()
Request
Accept
setUp
如果您使用单元测试来测试应用程序,则有一个预构建的 laravel assertHeader() 和 assertHeaderMissing()
函数可能会对您有所帮助。请参阅此处的官方文档。这是摘自 Docs 的代码片段,
$response->assertHeader($headerName, $value = null);
$response->assertHeaderMissing($headerName);
一个部分模拟的对象将允许你测试你的,而无需在 Laravel 的对象中测试辅助方法。换句话说,你真正需要知道的是你的宏是否有效。您无需测试是否可以构造 a 以及是否可以设置其标头。Illuminate\Http\Request::macro
Illuminate\Http\Request
Request
在以下测试中,我将使用 Mockery 设置对象的“部分”模拟版本。YamlRequest
当我们只需要模拟一个对象的多个方法时,部分模拟很有用,其余的方法可以自由地正常响应调用(即实现时)。
请参阅模拟文档创建部分模拟。
部分模拟将允许我们模拟 Laravel 对象中的方法,同时让您的宏像在生产环境中一样自由运行。Request
use YamlRequest;
use \Mockery;
class RequestTest extends TestCase
{
public function setUp()
{
parent::setUp();
$this->request = Mockery::mock(YamlRequest::class)->makePartial();
}
public function test_that_wants_yaml_returns_true_given_x-yaml_accept_header()
{
/**
* This line allows you to control the return value of
* Illuminate\Http\Request::getAcceptableContentTypes while your macro
* is running.
*/
$this->request->allows(
[
'getAcceptableContentTypes' => ['application/x-yaml', 'text/html']
]
);
$this->assertTrue($this->request->wantsYaml());
}
public function test_that_wants_yaml_returns_false_given_json_accept_header()
{
$this->request->allows(
[
'getAcceptableContentTypes' => ['application/json', 'text/html']
]
);
$this->assertFalse($this->request->wantsYaml());
}
}
评论
use
myMethod