尝试使用 IoC 容器在我的控制器测试中交换模型,但对象不是交换器
Trying to swap a model in my controller test with IoC Container, but object not swapper
我正在尝试使用 IoC 容器在测试时换出我的问题模型。虽然我已经创建了一个模拟模型,并在我的测试期间使用 App::instance() 尝试交换依赖关系,但我可以从 var_dump
中看到它不起作用。我的代码有什么问题?
<?php
class QuestionsControllerTest extends TestCase {
protected $mock;
public function __construct()
{
// This is how Net tuts tutorial instructed, but
// I got Eloquent not found errors
// $this->mock = Mockery::mock('Eloquent', 'Question');
// so I tried this instead, and it created the mock
$this->mock = Mockery::mock('App\Question');
}
public function tearDown()
{
Mockery::close();
}
public function testQuestionIndex()
{
// var_dump(get_class($this->mock)); exit; // outputs: Mockery_0_App_Question
// var_dump(get_class($this->app)); exit; // outputs: Illuminate\Foundation\Application
$this->mock
->shouldReceive('latest')
->once()
->andReturnSelf();
$this->mock
->shouldReceive('get') //EDIT: should be get
->once()
->andReturn('foo');
$this->app->instance('App\Question', $this->mock);
// dispatch route
$response = $this->call('GET', 'questions');
$this->assertEquals(200, $response->getStatusCode());
}
}
到目前为止还好吗?下面是我的问题控制器:
class QuestionsController extends Controller {
protected $question;
public function index(Question $question)
{
// var_dump(get_class($question)); exit; // Outputs App\Question when testing too
$questions = $question
->latest()
->get();
return view('questions.index', compact('questions'));
}
...
因此,如果不交换对象,无论如何它都不会注册对方法的调用:
Mockery\Exception\InvalidCountException: Method latest() from Mockery_0_App_Question should be called
exactly 1 times but called 0 times.
顺便说一下,我已经安装了 Mockery ~0.9、Laravel 5.0 和 PHPUnit ~4.0。非常感谢对此的任何帮助。
您收到此错误是因为您没有完全定义模拟。
你告诉你的 mock 它应该期望 latest
被调用一次,但你没有指定最近应该 return。在控制器的下一行调用 get
.
试试下面的代码
$this->mock
->shouldReceive('latest')
->once()
->andReturnSelf();
$this->mock
->shouldReceive('get') //EDIT: should be get
->once()
->andReturn('foo');
$this->app->instance('Question', $this->mock);
关于在 larvel 中测试控制器的非常好的文章 http://code.tutsplus.com/tutorials/testing-laravel-controllers--net-31456
我认为您在使用 instance()
时需要指定完整的命名空间。 Laravel 否则将假定模型位于全局命名空间 ('\Question') 中。
这应该有效:
$this->app->instance('App\Question', $this->mock);
现在关于另一个问题,你的模拟。既然你的观点想要一个集合,为什么不给它一个呢?如果你不想测试视图,你可以简单地实例化一个空集合并且 return that:
$this->mock
->shouldReceive('latest')
->once()
->andReturnSelf();
$this->mock
->shouldReceive('get')
->once()
->andReturn(new Illuminate\Database\Eloquent\Collection);
如果需要,您还可以检查视图是否已正确接收变量:
$response = $this->call('GET', 'questions');
$this->assertViewHas('questions');
我正在尝试使用 IoC 容器在测试时换出我的问题模型。虽然我已经创建了一个模拟模型,并在我的测试期间使用 App::instance() 尝试交换依赖关系,但我可以从 var_dump
中看到它不起作用。我的代码有什么问题?
<?php
class QuestionsControllerTest extends TestCase {
protected $mock;
public function __construct()
{
// This is how Net tuts tutorial instructed, but
// I got Eloquent not found errors
// $this->mock = Mockery::mock('Eloquent', 'Question');
// so I tried this instead, and it created the mock
$this->mock = Mockery::mock('App\Question');
}
public function tearDown()
{
Mockery::close();
}
public function testQuestionIndex()
{
// var_dump(get_class($this->mock)); exit; // outputs: Mockery_0_App_Question
// var_dump(get_class($this->app)); exit; // outputs: Illuminate\Foundation\Application
$this->mock
->shouldReceive('latest')
->once()
->andReturnSelf();
$this->mock
->shouldReceive('get') //EDIT: should be get
->once()
->andReturn('foo');
$this->app->instance('App\Question', $this->mock);
// dispatch route
$response = $this->call('GET', 'questions');
$this->assertEquals(200, $response->getStatusCode());
}
}
到目前为止还好吗?下面是我的问题控制器:
class QuestionsController extends Controller {
protected $question;
public function index(Question $question)
{
// var_dump(get_class($question)); exit; // Outputs App\Question when testing too
$questions = $question
->latest()
->get();
return view('questions.index', compact('questions'));
}
...
因此,如果不交换对象,无论如何它都不会注册对方法的调用:
Mockery\Exception\InvalidCountException: Method latest() from Mockery_0_App_Question should be called
exactly 1 times but called 0 times.
顺便说一下,我已经安装了 Mockery ~0.9、Laravel 5.0 和 PHPUnit ~4.0。非常感谢对此的任何帮助。
您收到此错误是因为您没有完全定义模拟。
你告诉你的 mock 它应该期望 latest
被调用一次,但你没有指定最近应该 return。在控制器的下一行调用 get
.
试试下面的代码
$this->mock
->shouldReceive('latest')
->once()
->andReturnSelf();
$this->mock
->shouldReceive('get') //EDIT: should be get
->once()
->andReturn('foo');
$this->app->instance('Question', $this->mock);
关于在 larvel 中测试控制器的非常好的文章 http://code.tutsplus.com/tutorials/testing-laravel-controllers--net-31456
我认为您在使用 instance()
时需要指定完整的命名空间。 Laravel 否则将假定模型位于全局命名空间 ('\Question') 中。
这应该有效:
$this->app->instance('App\Question', $this->mock);
现在关于另一个问题,你的模拟。既然你的观点想要一个集合,为什么不给它一个呢?如果你不想测试视图,你可以简单地实例化一个空集合并且 return that:
$this->mock
->shouldReceive('latest')
->once()
->andReturnSelf();
$this->mock
->shouldReceive('get')
->once()
->andReturn(new Illuminate\Database\Eloquent\Collection);
如果需要,您还可以检查视图是否已正确接收变量:
$response = $this->call('GET', 'questions');
$this->assertViewHas('questions');