[英]Use mockery to unit test a class with dependencies
我是测试的新手,我正在尝试创建一个涵盖NewsCreator create方法中第一个if语句的单元测试。
这个问题分为两个部分。
第一:我应该如何实例化NewsCreator以处理模拟的验证器和存储库?
第二:测试此路径的正确方法是什么?
这是我的控制器方法,该方法调用需要测试的类:
public function store()
{
$creator = new NewsCreator($this);
return $creator->create(Input::all());
}
这是我要测试的类,NewsCreator:
<?php namespace WHS\Portal\News;
class NewsCreator {
protected $listener;
protected $repository;
protected $validator;
protected $errors;
public function __construct($listener, NewsRepositoryInterface $repository, NewsValidator $validator)
{
$this->listener = $listener;
$this->repository = $repository;
$this->validator = $validator;
$this->errors = [];
}
public function create($data)
{
if($this->validator->fails($data))
{
return $this->listener->newsCreationFails($this->validator->messages());
}
if($this->repository->create($data))
{
return $this->listener->newsCreationSucceeds();
}
return $this->listener->newsCreationFails($this->errors);
}
}
这是我尝试编写的测试,但是由于异常而失败:
2) WHS\\Portal\\Tests\\News\\NewsCreatorTest::test_failed_validation Mockery\\Exception\\InvalidCountException: Method fails("foo") from Mockery_1_WHS_Portal_News_NewsValidator should be called exactly 1 times but called 0 times.
<?php namespace WHS\Portal\Tests\News;
use TestCase;
use Mockery as m;
class NewsCreatorTest extends TestCase {
public function tearDown()
{
m::close();
}
public function test_failed_validation()
{
$newsRepo = m::mock('\WHS\Portal\News\DbNewsRepository["create"]');
$newsValidator = m::mock('\WHS\Portal\News\NewsValidator["fails"]');
$listener = new NewsListenerStub();
$listener = m::mock($listener)->makePartial();
$newsValidator->shouldReceive('fails')->with('foo')->once()->andReturn(true);
$listener->shouldReceive('newsCreationFails')->once()->with('foo')->andReturn();
$newsCreator = new \WHS\Portal\News\NewsCreator($listener,$newsRepo,$newsValidator);
$newsCreator->create([]);
}
}
更新的测试:
use TestCase;
use Mockery as m;
class NewsCreatorTest extends TestCase {
public function tearDown()
{
m::close();
}
public function test_failed_validation()
{
$newsRepo = m::mock('\WHS\Portal\News\DbNewsRepository["create"]');
$newsValidator = m::mock('\WHS\Portal\News\NewsValidator["fails"]');
$listener = m::mock('\WHS\Portal\Tests\News\NewsListenerStub["newsCreationFails"]');
$newsValidator->shouldReceive('fails')->with([])->once()->andReturn(true);
$newsValidator->shouldReceive('messages')->once();
$listener->shouldReceive('newsCreationFails')->once()->with('foo')->andReturn('foo-bar');
$newsCreator = new \WHS\Portal\News\NewsCreator($listener,$newsRepo,$newsValidator);
$result = $newsCreator->create([]);
$this->assertEquals('foo-bar', $result);
}
}
存根类:
class NewsListenerStub
{
public function newsCreationFails($data)
{
return $data;
}
}
请帮忙。
谢谢。
该方法fails()
在您的类中使用$data
参数调用。 在单元测试中,您将作为数据create([])
传递一个空数组。 您对validateatorMock的期望参数期望使用参数foo
调用fail fails()
。 您必须更改它以匹配空数组。
$newsValidator->shouldReceive('fails')->with([])->once()->andReturn(true);
另外,您还必须在validator->messages()
上指定validator->messages()
方法,因为该方法也在您的类中被调用。
$newsValidator->shouldReceive('messages')->once();
为了使此测试真正NewsCreationFails
,您必须断言NewsCreationFails
的结果与create()
的返回值匹配。
$listener->shouldReceive('newsCreationFails')->once()->with('foo')->andReturn('foo-bar');
...
$result = $newsCreator->create([]);
$this->assertEquals('foo-bar', $result);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.