Ложные объекты, которые поддерживают методы сцепления - PullRequest
7 голосов
/ 20 ноября 2010

Мне интересно, есть ли достаточно лаконичный способ макетирования объектов, которые поддерживают цепочку методов ... поэтому, например, объект запроса к базе данных может иметь вызов метода, который выглядит следующим образом:

$result = $database->select('my_table')->where(array('my_field'=>'a_value'))->limit(1)->execute();

Проблема возникает, если мне нужно смоделировать два разных запроса на выборку, чтобы они возвращали разные результаты.Любые идеи?

Речь идет именно о PHPUnit, но опыт других структур модульного тестирования поможет.

Ответы [ 3 ]

14 голосов
/ 20 ноября 2010

Я не уверен, что это то, что вы ищете, поэтому, пожалуйста, оставьте комментарий:

class StubTest extends PHPUnit_Framework_TestCase
{
    public function testChainingStub()
    {
        // Creating the stub with the methods to be called
        $stub = $this->getMock('Zend_Db_Select', array(
            'select', 'where', 'limit', 'execute'
        ), array(), '', FALSE);

        // telling the stub to return a certain result on execute
        $stub->expects($this->any())
             ->method('execute')
             ->will($this->returnValue('expected result'));

        // telling the stub to return itself on any other calls
        $stub->expects($this->any())
             ->method($this->anything())
             ->will($this->returnValue($stub));

        // testing that we can chain the stub
        $this->assertSame(
            'expected result',
            $stub->select('my_table')
                 ->where(array('my_field'=>'a_value'))
                 ->limit(1)
                 ->execute()
        );
    }
}

Вы можете совместить это с ожиданиями:

class StubTest extends PHPUnit_Framework_TestCase
{
    public function testChainingStub()
    {
        // Creating the stub with the methods to be called
        $stub = $this->getMock('Zend_Db_Select', array(
            'select', 'where', 'limit', 'execute'
        ), array(), '', FALSE);

        // overwriting stub to return something when execute is called
        $stub->expects($this->exactly(1))
             ->method('execute')
             ->will($this->returnValue('expected result'));

        $stub->expects($this->exactly(1))
             ->method('limit')
             ->with($this->equalTo(1))
             ->will($this->returnValue($stub));

        $stub->expects($this->exactly(1))
             ->method('where')
             ->with($this->equalTo(array('my_field'=>'a_value')))
             ->will($this->returnValue($stub));

        $stub->expects($this->exactly(1))
             ->method('select')
             ->with($this->equalTo('my_table'))
             ->will($this->returnValue($stub));

        // testing that we can chain the stub
        $this->assertSame(
            'expected result',
            $stub->select('my_table')
                 ->where(array('my_field'=>'a_value'))
                 ->limit(1)
                 ->execute()
        );
    }
}
1 голос
/ 28 ноября 2014

Я знаю, что это старый вопрос, но он может помочь будущему гуглеру.

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

Пример использования:

 // Creating a new mock for SimpleClassForMocking
 $mock = ShortifyPunit::mock('SimpleClassForMocking');

  ShortifyPunit::when($mock)->first_method()
                            ->second_method(2,3)->returns(1);

  ShortifyPunit::when($mock)->first_method()
                            ->second_method(2,3,4)->returns(2);

  ShortifyPunit::when($mock)->first_method(1)
                            ->second_method(2,3,4)->returns(3);

  ShortifyPunit::when($mock)->first_method(1,2,3)
                            ->second_method(1,2)->third_method()->returns(4);

  $mock->first_method()->second_method(2,3); // returns 1
  $mock->first_method()->second_method(2,3,4); // returns 2
  $mock->first_method(1)->second_method(2,3,4); // returns 3
  $mock->first_method(1,2,3)->second_method(1,2)->third_method(); // return 4

GitHub:

https://github.com/danrevah/ShortifyPunit#stubbing-method-chanining

0 голосов
/ 20 ноября 2010

Возможно, это не тот ответ, который вы ищете, но пару лет назад я написал фиктивную инфраструктуру объектов, которая будет обрабатывать такого рода утверждение утверждения «зависит от ввода»:

http://code.google.com/p/yaymock/

http://code.google.com/p/yaymock/wiki/Expectations

Я написал его для использования в модульных тестах на основе Swift Mailer, но он не получил широкого распространения ни в каких других проектах (о которых я знаю). Цель состояла в том, чтобы обеспечить лучший контроль и интроспекцию вызовов фиктивных объектов, чем те, которые предусмотрены PHPUnit и SimpleTest.

...