我是新手测试,我使用 codeception和phpunit 来做一些TDD。
但是,我的方法有很多代码。我是否使用过最佳做法?有没有办法提高代码的准备程度,是否更干净?
class NewsFormHandlerTest extends \Codeception\Test\Unit
{
/**
* @var \UnitTester
*/
protected $tester;
protected function _before()
{
}
protected function _after()
{
}
private function getFormMock(){
return $this->getMockBuilder(FormInterface::class)
->disableOriginalConstructor()
->getMock();
}
private function getNewsManagerMock(){
return $this->getMockBuilder(INewsManager::class)
->disableOriginalConstructor()
->getMock();
}
// tests
public function testShouldHandleASuccessfulFormSubmissionForAddANews()
{
// prepare
$request = new \Symfony\Component\HttpFoundation\Request();
$news = new News();
$form = $this->getFormMock();
$form->expects($this->once())
->method('isValid')
->will($this->returnValue(true));
$form->expects($this->once())
->method('submit');
$form->expects($this->once())
->method('getData')
->will($this->returnValue($news));
$newsManager = $this->getNewsManagerMock();
$newsManager->expects($this->once())
->method('add');
$user = Stub::make(WebserviceUser::class, []);
// test
$handler = new NewsFormHandler($newsManager, $user);
$newsReturned = $handler->handle($form, $request, NewsFormHandler::ADD);
// assert
$this->assertInstanceOf(News::class, $newsReturned);
$this->assertEquals($news, $newsReturned);
}
public function testShouldHandleASuccessfulFormSubmissionForEditANews()
{
// prepare
$request = new \Symfony\Component\HttpFoundation\Request();
$news = new News();
$form = $this->getFormMock();
$form->expects($this->once())
->method('isValid')
->will($this->returnValue(true));
$form->expects($this->once())
->method('submit');
$form->expects($this->once())
->method('getData')
->will($this->returnValue($news));
$newsManager = $this->getNewsManagerMock();
$newsManager->expects($this->once())
->method('edit');
$user = Stub::make(WebserviceUser::class, []);
// test
$handler = new NewsFormHandler($newsManager, $user);
$newsReturned = $handler->handle($form, $request, NewsFormHandler::EDIT);
// assert
$this->assertInstanceOf(News::class, $newsReturned);
$this->assertEquals($news, $newsReturned);
}
public function testFailFormWithInvalidData()
{
// prepare
$request = new \Symfony\Component\HttpFoundation\Request();
$form = $this->getFormMock();
$form->expects($this->once())
->method('isValid')
->will($this->returnValue(false));
$newsManager = $this->getNewsManagerMock();
$newsManager->expects($this->never())
->method('edit');
$this->expectException(InvalidFormException::class);
$user = Stub::make(WebserviceUser::class, []);
// test
$handler = new NewsFormHandler($newsManager, $user);
$newsReturned = $handler->handle($form, $request, NewsFormHandler::ADD);
// assert
$this->assertNull($newsReturned);
}
}
答案 0 :(得分:1)
您可以将testShouldHandleASuccessfulFormSubmissionForAddANews和testShouldHandleASuccessfulFormSubmissionForEditANews的主体提取到其他方法,例如$ action ='add'|'edit'(或使用您定义的内容NewsFormHandler :: EDIT等),因为它们几乎是相同。
您可以将上述方法中的模拟创建提取到单个参数化方法,因为该过程几乎相同(将差异作为方法参数传递并让它执行脏工作)。
您还可以使用BDD样式添加一些可读性,如第http://codeception.com/docs/05-UnitTests#BDD-Specification-Testing页中的示例