2013-11-20 131 views
1

仍然在学习如何测试PHPPHPUnit的测试功能

我现在有一个工作界面(我认为) - 的功能之一是为了创造出一系列的,我现在想测试是做记录。我承认我对测试知之甚少,所以比知识有更多的问题。

所以

我的界面目前看起来是这样的:

interface TicketCreatorInterface { 

public function createTicket($input, $book); 

} 

我的 '仓库' 类看起来是这样的:

Class TicketCreator implements TicketCreatorInterface { 

protected $ticket; 

public function __construct(TicketAudit $ticketAudit) 
{ 
    $this->ticket = $ticketAudit; 
} 

public function createTicket($input, $book) { 

    $counter = $input['start']; 

    while($counter <= $input['end']) { 

     $this->$ticket->create(array(
      'ticketnumber'=>$counter, 
      'status'=>'unused', 
      'active'=>1 
      )); 

     $this->ticket->book()->associate($book); 

     $counter = $counter+1; 

    } 

    return $counter; 



} 

而我试图在测试看起来是这样的:

public function testCreateCreatesTickets(TicketCreatorInterface $ticketCreator) { 

    //arrange 
    $book = Mockery::mock('Book'); 


    //act 
    $response = $ticketCreator->createTicket(array('start'=>1000, 'end'=>1001), $book); 

    // Assert... 
    $this->assertEquals(true, $response); 
} 

我首先尝试没有打印接口,因为没有收到没有任何对象的错误。我试图创建界面上的一个实例,但你不能这样做,因此诉诸于功能

我得到的错误typehinting当我运行测试:

Argument 1 passed to TicketCreatorTest::testCreateCreatesTickets() must implement interface TicketCreatorInterface, none given 

创建界面是一种新的方法对我来说,所以还不完全了解它。

那么我该如何测试这个函数是否按预期创建了一张票?

我在内存数据库

回答

6

您需要在您的测试来调用该方法来创建你的TicketCreator的实例与源码测试的模型。测试改成这样:

public function testCreateCreatesTickets() { 

    //arrange 
    $book = Mockery::mock('Book'); 
    $ticketAudit = Mockery::mock('TicketAudit'); 
    $ticketCreator = new TicketCreator($ticketAudit); 


    //act 
    $response = $ticketCreator->createTicket(array('start'=>1000, 'end'=>1001), $book); 

    // Assert... 
    $this->assertEquals(true, $response); 
} 

既然你需要在你的构造函数TicketAudit,你还需要创建一个对象的模拟,并把它传递到您的构造函数。

PHPUnit为测试用例提供参数的唯一时间是当您有数据提供程序或测试依赖于另一个测试时。

http://phpunit.de/manual/current/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.data-providers

http://phpunit.de/manual/current/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.examples.StackTest2.php

请记住,你不创建一个接口的实例。如果我想确保你的对象实现了一个接口,我将创建一个测试来检查对象是否是使用assertInstanceOf的接口实例。

+0

谢谢。这工作。我现在发现的问题是,因为ticketAudit被嘲笑了一些需要该对象的功能,并且它的所有属性都不再起作用。现在我的错误是'调用一个非对象的成员函数associate()有没有办法解决这个问题? – Ray

+0

我对Mockery不熟悉,但您需要在模拟中设置这些方法的行为,以便仅测试TicketCreator类而不需要依赖ticketAudit功能。 – Schleis

+0

这个错误是因为'book()'方法返回null。你需要设置你的嘲讽当这个值被调用时返回一些东西。尽管你这样做的事实是一种代码异味,你应该考虑改变你的代码,以便你不需要让模拟对象返回模拟对象。 – Schleis