SimpleTest Mock объекты: очистка ожиданий - PullRequest
0 голосов
/ 26 октября 2009

Короткий вопрос: Есть ли способ сбросить объект-заглушку в SimpleTest, удалив все ожидания?

Более подробное объяснение:

У меня есть класс, который я тестирую с использованием SimpleTest , и у меня возникли некоторые проблемы с объектами Mock, которые он использует.

Класс является Logger, а внутри регистратора находится ряд Writer объектов (FileWriter, EmailWriter и т. Д.). Вызов метода Logger::log() выполняет некую закулисную логику и направляет сообщение правильному автору. Писатели кэшируются в классе Logger для сохранения каждого экземпляра каждый раз.

В своих модульных тестах я установил Logger, создал и добавил в него несколько объектов Mock Writer, а затем использовал методы, подобные MockDBWriter->expectOnce(), чтобы проверить, работает ли Logger.

Теперь проблема в том, что я хочу протестировать другую функцию Logger, но ожидания expectOnce все еще действуют и приводят к сбою моих последующих тестов.

function testWritesMessageOK() {
    $log = Logger::getInstance();
    $mock = new MockFileWriter($this);

    $log->addWriter($mock);

    $mock->expectOnce("write", "Message");

    $log->write("Message");    // OK
}

// this is just an example - the actual test is much less inane
function testNumberOfWrites() {
    $log = Logger::getInstance();
    $mock = $log->getWriter();

    $mock->expectCallCount('write', 2);

    $log->write("One");    // fail - it doesn't match "Message"
    $log->write("Two");
}

Есть ли способ сбросить объект Mock, убрав все ожидания?

1 Ответ

2 голосов
/ 26 октября 2009

Использовать отдельные макеты.

Или:

$mock = $log->getWriter();
$mock = new $mock;

Или:

$mock = new MockFileWriter($this);
// And then:
$mock = new MockDBWriter($this);
// And then:
$mock = new MockEmailWriter($this);
// etc.

Я бы поставил под сомнение мудрость писателей-кешировщиков, чтобы спасти воссоздание. Если вы делаете создание экземпляра дешевой операцией (то есть не создаете соединение с БД или что-либо еще) и откладываете подобные вещи до тех пор, пока вам действительно не понадобится соединение, такое как первый запрос, тогда вам не нужно будет кэшировать, и вся эта проблема может уходи.

Другая вещь, которую вы можете сделать, это вызвать конструктор SimpleMock.

$mock = $log->getWriter();
$mock->SimpleMock();

Что все это сделает:

/**
 *    Creates an empty action list and expectation list.
 *    All call counts are set to zero.
 *    @access public
 */
function SimpleMock() {
    $this->_actions = &new SimpleCallSchedule();
    $this->_expectations = &new SimpleCallSchedule();
    $this->_call_counts = array();
    $this->_expected_counts = array();
    $this->_max_counts = array();
    $this->_expected_args = array();
    $this->_expected_args_at = array();
    $test = &$this->_getCurrentTestCase();
    $test->tell($this);
}

Единственная проблема с этим заключается в том, что в конце вызывается tell(), что вызовет повторный вызов SimpleMock::atTestEnd() при подсчете ожиданий. Но это можно исправить с помощью этого:

// $this should == the test case in question
array_pop($this->_observers);

Этот ответ основан на версии 1.0.1 SimpleTest.

...