【问题标题】:phpunit test function in interface接口中的phpunit测试函数
【发布时间】:2013-12-05 01:58:00
【问题描述】:

还在学习如何测试php

我现在有一个工作界面(我认为) - 其中一个功能旨在创建一系列我现在想要测试的记录。我承认我对测试知之甚少,因此问题多于知识。

所以

我的界面目前是这样的:

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);
 }

我首先尝试了没有输入界面,因为没有这个我得到了没有对象的错误。我尝试在界面上创建一个实例,但你不能这样做,所以在函数中使用类型提示

我运行测试时得到的错误是:

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

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

那么我怎样才能测试这个函数是否按预期创建票证?

我已经在内存数据库中使用 sqlite 测试过模型

【问题讨论】:

    标签: php unit-testing interface phpunit


    【解决方案1】:

    您需要在测试中创建 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 的接口的一个实例。

    【讨论】:

    • 谢谢。那行得通。不过,我现在发现的问题是,由于ticketAudit 被模拟了一些需要该对象的功能,并且它的所有属性都不再起作用。我现在的错误是Call to a member function associate() on a non-object 有没有办法解决这个问题?
    • 我对 Mockery 不熟悉,但您需要在您的 mock 中设置这些方法的行为,以便您只测试 TicketCreator 类而不需要依赖于 ticketAudit 功能。
    • 该错误是因为方法 book() 返回 null。您需要设置模拟以在调用该值时返回某些内容。尽管您这样做是一种代码异味,但您应该考虑更改您的代码,这样您就不需要让模拟对象返回模拟对象。
    • Mockery 允许在 mock 对象上定义 demeter 链,因此您可以防止错误: $ticketAudit->shouldReceive('book->associate)->andReturn("whatever_needed");
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-01
    • 2011-06-22
    • 1970-01-01
    • 2015-01-19
    • 1970-01-01
    • 2016-06-12
    • 2013-08-02
    相关资源
    最近更新 更多