PHPUnit “Дразнил метод, не существует”. когда использование $mock-> ожидает ($this-> в (…))

Я столкнулся со странной проблемой с фиктивными объектами PHPUnit. У меня есть метод, который нужно назвать дважды, таким образом, я использую "в" matcher. Это работает впервые, метод называют, но по некоторым причинам, во второй раз это называют, я получаю "Дразнивший метод, не существует".. Я использовал "в" matcher прежде и никогда не сталкивался с этим.

Мой код смотрит что-то как:

class MyTest extends PHPUnit_Framework_TestCase
{
    ...

    public function testThis()
    {
        $mock = $this->getMock('MyClass', array('exists', 'another_method', '...'));
        $mock->expects($this->at(0))
             ->method('exists')
             ->with($this->equalTo('foo'))
             ->will($this->returnValue(true));

        $mock->expects($this->at(1))
             ->method('exists')
             ->with($this->equalTo('bar'))
             ->will($this->returnValue(false));
    }

    ...
}

Когда я запускаю тест, я добираюсь:

Expectation failed for method name is equal to <string:exists> when invoked at sequence index 1.
Mocked method does not exist.

Если я удаляю второй matcher, я не получаю ошибку.

Кто-либо столкнулся с этим прежде?

Спасибо!

38
задан rr. 29 July 2010 в 22:34
поделиться

3 ответа

Проблема в конечном итоге заключалась в том, как я понял, что сопоставление "at" работает. Кроме того, мой пример не был дословным, как в моем модульном тесте. Я думал, что счетчик сопоставления «at» работает для каждого запроса, где он действительно работает для каждого экземпляра объекта.

Пример:

class MyClass {

    public function exists($foo) {
        return false;
    }

    public function find($foo) {
        return $foo;
    }
}

Неверно:

class MyTest extends PHPUnit_Framework_TestCase
{

    public function testThis()
    {
        $mock = $this->getMock('MyClass');
        $mock->expects($this->at(0))
             ->method('exists')
             ->with($this->equalTo('foo'))
             ->will($this->returnValue(true));

        $mock->expects($this->at(0))
             ->method('find')
             ->with($this->equalTo('foo'))
             ->will($this->returnValue('foo'));

        $mock->expects($this->at(1))
             ->method('exists')
             ->with($this->equalTo('bar'))
             ->will($this->returnValue(false));

        $this->assertTrue($mock->exists("foo"));
        $this->assertEquals('foo', $mock->find('foo'));
        $this->assertFalse($mock->exists("bar"));
    }

}

Правильно:

class MyTest extends PHPUnit_Framework_TestCase
{

    public function testThis()
    {
        $mock = $this->getMock('MyClass');
        $mock->expects($this->at(0))
             ->method('exists')
             ->with($this->equalTo('foo'))
             ->will($this->returnValue(true));

        $mock->expects($this->at(1))
             ->method('find')
             ->with($this->equalTo('foo'))
             ->will($this->returnValue('foo'));

        $mock->expects($this->at(2))
             ->method('exists')
             ->with($this->equalTo('bar'))
             ->will($this->returnValue(false));

        $this->assertTrue($mock->exists("foo"));
        $this->assertEquals('foo', $mock->find('foo'));
        $this->assertFalse($mock->exists("bar"));
    }

}
42
ответ дан 27 November 2019 в 03:37
поделиться

Насколько я могу судить по демонстрационному коду, он должен работать. Я создал рабочий пример на тот случай, если вы используете более старую версию PHPUnit и хотите проверить, работает ли она и для вас тоже.

В случае, если это не поможет, может быть, вы могли бы предоставить немного больше (в лучшем случае исполняемого) кода? :)

<?php

class MyTest extends PHPUnit_Framework_TestCase
{

    public function testThis()
    {
        $mock = $this->getMock('MyClass');
        $mock->expects($this->at(0))
             ->method('exists')
             ->with($this->equalTo('foo'))
             ->will($this->returnValue(true));

        $mock->expects($this->at(1))
             ->method('exists')
             ->with($this->equalTo('bar'))
             ->will($this->returnValue(false));

        $this->assertTrue($mock->exists("foo"));
        $this->assertFalse($mock->exists("bar"));
    }

}

class MyClass {

    public function exists($foo) {
        return false;
    }
}

печать

phpunit MyTest.php
PHPUnit 3.4.15 by Sebastian Bergmann.

.

Time: 0 seconds, Memory: 4.25Mb

OK (1 test, 3 assertions)
1
ответ дан 27 November 2019 в 03:37
поделиться

Вы уверены, что включили MyClass в свой тест? У меня были некоторые ошибки неопределенного метода при насмешке над классом / интерфейсом без его включения.

0
ответ дан 27 November 2019 в 03:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: