使用PHPUnit和Mockery进行Laravel测试 – 在Controller测试中设
|
在最终让我的愚蠢简单测试通过之后,我感觉我没有正确地做到这一点.
我有一个SessionsController,负责显示登录页面并记录用户. 我决定不使用外墙,这样我就不必延长Laravel的TestCase并在我的单元测试中获得性能.因此,我已通过控制器注入所有依赖项,如此 – SessionsController – 构造函数 public function __construct(UserRepositoryInterface $user,AuthManager $auth,Redirector $redirect,Environment $view )
{
$this->user = $user;
$this->auth = $auth;
$this->redirect = $redirect;
$this->view = $view;
}
我已经完成了必要的变量声明和使用命名空间,我不打算在这里包含它作为不必要的. create方法检测用户是否被授权,如果是,则将其重定向到主页,否则显示登录表单. SessionsController – 创建 public function create()
{
if ($this->auth->user()) return $this->redirect->to('/');
return $this->view->make('sessions.login');
}
现在进行测试,我是新手,所以请耐心等待. SessionsControllerTest class SessionsControllerTest extends PHPUnit_Framework_TestCase {
public function tearDown()
{
Mockery::close();
}
public function test_logged_in_user_cannot_see_login_page()
{
# Arrange (Create mocked versions of dependencies)
$user = Mockery::mock('GlennRepositoriesUserUserRepositoryInterface');
$authorizedUser = Mockery::mock('IlluminateAuthAuthManager');
$authorizedUser->shouldReceive('user')->once()->andReturn(true);
$redirect = Mockery::mock('IlluminateRoutingRedirector');
$redirect->shouldReceive('to')->once()->andReturn('redirected to home');
$view = Mockery::mock('IlluminateViewEnvironment');
# Act (Attempt to go to login page)
$session = new SessionsController($user,$authorizedUser,$redirect,$view);
$result = $session->create();
# Assert (Return to home page)
}
}
这一切都通过了,但我不想为我在SessionsControllerTest中编写的每个测试声明所有这些模拟的依赖项.有没有办法在构造函数中声明这些模拟的依赖项?然后通过变量调用它们进行模拟?
您可以使用setUp方法声明整个测试类的全局依赖项.它与您当前使用的tearDown方法类似:
public function setUp()
{
// This method will automatically be called prior to any of your test cases
parent::setUp();
$this->userMock = Mockery::mock('GlennRepositoriesUserUserRepositoryInterface');
}
但是,如果您的模拟设置在测试之间有所不同,那么这将不起作用.对于这种情况,您可以使用辅助方法: protected function getAuthMock($isLoggedIn = false)
{
$authorizedUser = Mockery::mock('IlluminateAuthAuthManager');
$authorizedUser->shouldReceive('user')->once()->andReturn($isLoggedIn);
}
然后当你需要auth mock时,你可以调用getAuthMock.这可以大大简化您的测试. 然而 我认为你没有正确测试你的控制器.您不应该自己实例化控制器对象,而应该使用Laravel的TestCase类中存在的调用方法.尝试查看this article关于Jeffrey Way测试Laravel控制器的信息.我认为你希望在你的测试中做更多的事情: class SessionsControllerTest extends TestCase
{
public function setUp()
{
parent::setUp();
}
public function tearDown()
{
Mockery::close();
}
public function test_logged_in_user_cannot_see_login_page()
{
// This will bind any instances of the Auth manager during
// the next request to the mock object returned from the
// function below
App::instance('IlluminateAuthManager',$this->getAuthMock(true));
// Act
$this->call('/your/route/to/controller/method','GET');
// Assert
$this->assertRedirectedTo('/');
}
protected function getAuthMock($isLoggedIn)
{
$authMock = Mockery::mock('IlluminateAuthManager');
$authMock->shouldReceive('user')->once()->andReturn($isLoggedIn);
return $authMock;
}
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
