PHPUnit Symfony测试用例错误
我是Symfony的新手,我已经编写了一个小应用程序,现在必须添加单元测试,这是我的控制器:PHPUnit Symfony测试用例错误,php,symfony,phpunit,Php,Symfony,Phpunit,我是Symfony的新手,我已经编写了一个小应用程序,现在必须添加单元测试,这是我的控制器: <?php namespace myBundle\Controller; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; use Sym
<?php
namespace myBundle\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RedirectResponse;
class IndexController extends AbstractController
{
/**
* @param \Symfony\Component\HttpFoundation\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function indexAction(Request $request)
{
if ($this->getRequest()->isMethod('POST')) {
// Do Something
}
// Do Something otherwise
}
}
当我运行此测试时,我得到以下结果:
PHP致命错误:调用成员函数get()
基本上是在下面这一行
如果($this->getRequest()->isMethod('POST')){
这告诉我容器为空(我通过打印容器的转储来验证它)
知道我在这里遗漏了什么吗,或者有没有一种方法可以提供容器作为测试的依赖项
我真的很感谢你的帮助
谢谢
FI您试图模拟要测试的类:
$this->testController=
$this->getMockBuilder('myBundle\Controller\IndexController')
->disableOriginalConstructor()
->getMock();
实际上,您应该实例化正在测试的类,并模拟或存根它的协作者
然而,在这个特定的场景中,不要编写单元测试,而是编写一个功能测试。有一章将对您有所帮助
您的控制器使用了大量的框架类(不属于您的类),您也不应该对它们进行模拟。这就是为什么在这种情况下功能测试更好的原因。此外,请确保您将尽可能多的代码移出控制器,以便您可以正确地对该部分进行单元测试(并编写尽可能少的功能测试)
同时,阅读一些关于单元测试的书籍(按以下顺序):
$this->testController=
$this->getMockBuilder('myBundle\Controller\IndexController')
->disableOriginalConstructor()
->getMock();
实际上,您应该实例化正在测试的类,并模拟或存根它的协作者
然而,在这个特定的场景中,不要编写单元测试,而是编写一个功能测试。有一章将对您有所帮助
您的控制器使用了大量的框架类(不属于您的类),您也不应该对它们进行模拟。这就是为什么在这种情况下功能测试更好的原因。此外,请确保您将尽可能多的代码移出控制器,以便您可以正确地对该部分进行单元测试(并编写尽可能少的功能测试)
同时,阅读一些关于单元测试的书籍(按以下顺序):
controller
类的控制器编写单元测试。正如您刚才注意到的,模拟容器成为一场噩梦。我会显式地或相反地注入所有依赖项。如果您在浏览器中测试您的网页,它是否工作?什么类型的类是AbstractController
?您是否也考虑过使用Symfony\Bundle\FrameworkBundle\Test\WebTestCase
而不是\PHPUnit\u Framework\u TestCase
?@honzalilak是的,我尝试过Symfony\Bundle\FrameworkBundle\Test\WebTestCase
并且我拥有的抽象控制器不需要任何东西,我只是添加有关日志记录和添加一些JS的信息我不会为扩展FrameworkBundle中的controller
类的控制器编写单元测试。正如您刚才注意到的,模拟容器变成了一场噩梦。我会显式地或相反地插入所有依赖项。如果您在浏览器中测试您的网页,它是否工作?什么类型的类是AbstractController
?您是否也考虑过使用Symfony\Bundle\FrameworkBundle\Test\WebTestCase
而不是\PHPUnit\u Framework\u TestCase
?@honzalilak是的,我尝试过Symfony\Bundle\FrameworkBundle\Test\WebTestCase
并且我拥有的抽象控制器不需要任何东西,我只需要添加有关日志记录和添加一些JS的信息作为一项服务,我得到了一个容器,但请求仍然为空,即$this->getRequest()==NULLIt不会神奇地出现在那里。这是您应该为使用第三方类的代码编写集成测试而不是单元测试的原因之一-您可能错误地假设了第三方类为您做了什么。Symfony使用一个侦听器设置请求对请求堆栈服务。您很可能没有这样做e在测试中也是一样,因此getRequest()返回null。另外,不要在控制器中使用getRequest(),而是将其传递给action方法。您可以在单元测试中通过它。即使作为服务,我获取容器,但请求仍然为null,即$this->getRequest()==NULLIt不会神奇地出现在那里。这是您应该为使用第三方类的代码编写集成测试而不是单元测试的原因之一-您可能错误地假设了第三方类为您做了什么。Symfony使用一个侦听器设置请求对请求堆栈服务。您很可能没有这样做在测试中也是如此,因此getRequest()返回null。另外,不要在控制器中使用getRequest(),而是将其传递给action方法。您将能够在单元测试中传递它。
class IndexControllerTest extends \PHPUnit_Framework_TestCase
{
protected $testController;
public function setUp()
{
$this->testController =
$this->getMockBuilder('myBundle\Controller\IndexController')
->disableOriginalConstructor()
->getMock();
}
public function testPostSaveActionWithBadRequest()
{
$expectation = 'Some text ';
$response = $this->testController->indexAction(new Request);
$this->assertInstanceOf(
'Symfony\Component\HttpFoundation\JsonResponse',
$response
);
$content = json_decode($response->getContent());
$this->assertEquals($expectation, $content->error);
}
}