我是测试控制器的新手,我遇到了一个方法问题()。我相信我在测试中遗漏了一些内容,或者我的Controller / Repository设计不正确。
我正在编写的应用程序基本上就是那种安全的“一次性”工具之一。在您创建注释的位置,系统会为您提供URL,一旦检索到该URL,便会删除该注释。我实际上已经编写了应用程序,但我要回去为练习编写测试(我知道这是向后的)。
我的控制器:
use OneTimeNote\Repositories\NoteRepositoryInterface as Note;
class NoteController extends \Controller {
protected $note;
public function __construct(Note $note)
{
$this->note = $note;
}
public function getNote($url_id, $key)
{
$note = $this->note->find($url_id, $key);
if (!$note) {
return \Response::json(array('message' => 'Note not found'), 404);
}
$this->note->delete($note->id);
return \Response::json($note);
}
...
我已将我的Note界面注入我的控制器,一切都很顺利。
我的测试
use \Mockery as M;
class OneTimeNoteTest extends TestCase {
public function setUp()
{
parent::setUp();
$this->mock = $this->mock('OneTimeNote\Repositories\EloquentNoteRepository');
}
public function mock($class)
{
$mock = M::mock($class);
$this->app->instance($class, $mock);
return $mock;
}
public function testShouldReturnNoteObj()
{
// Should Return Note
$this->mock->shouldReceive('find')->once()->andReturn('test');
$note = $this->call('GET', '/note/1234567890abcdefg/1234567890abcdefg');
$this->assertEquals('test', $note->getContent());
}
}
...
我得到的错误
1) OneTimeNoteTest::testShouldReturnNoteObj
ErrorException: Trying to get property of non-object
/Users/andrew/laravel/app/OneTimeNote/Controllers/NoteController.php:24
第24行是参考我的控制器中找到的这一行:
$this->note->delete($note->id);
基本上我的抽象存储库方法delete()显然找不到$ note-> id,因为它在测试环境中确实不存在。我应该在测试中创建一个Note并尝试实际删除吗?或者这应该是模型测试?如你所见,我需要帮助,谢谢!
----- 更新 -----
我试图将存储库存根以返回一个Note对象,正如Dave Marshall在他的回答中提到的那样,但我现在收到了另一个错误。
1) OneTimeNoteTest::testShouldReturnNoteObj
BadMethodCallException: Method Mockery_0_OneTimeNote_Repositories_EloquentNoteRepository::delete() does not exist on this mock object
我的存储库中有一个delete()方法,当我在浏览器中测试路径时,我知道它正在工作。
public function delete($id)
{
Note::find($id)->delete();
}
答案 0 :(得分:3)
您正在记录注释存储库以返回字符串,然后PHP尝试检索字符串的id属性,从而导致错误。
您应该存储存储库以返回Note对象,例如:
$this->mock->shouldReceive('find')->once()->andReturn(new Note());
答案 1 :(得分:1)
根据Dave的回答,我能够弄清楚我的问题是什么。我没有嘲笑delete()方法。我不明白是否需要在我的控制器中模拟每个被调用的方法。
我刚刚添加了这一行:
$mock->shouldReceive('delete')->once()->andReturnNull();
由于我的删除方法只是在找到后删除了注释,我继续嘲笑它但将其设置为返回null。