Как я могу издеваться над внешним веб-запросом в PHPUnit?

Я работаю над настройкой набора тестов для проекта PHP Propel . используя Phactory и PHPUnit . В настоящее время я пытаюсь провести модульное тестирование функция, которая делает внешний запрос, и я хочу заглушить макет ответ на этот запрос.

Вот фрагмент класса, который я пытаюсь протестировать:

class Endpoint {
 ...
  public function parseThirdPartyResponse() {
    $response = $this->fetchUrl("www.example.com/api.xml");
    // do stuff and return 
   ...
  }

  public function fetchUrl($url) {
    return file_get_contents($url);
  }
 ...

И вот тестовая функция, которую я пытаюсь написать.

// my factory, defined in a seperate file
Phactory::define('endpoint', array('identifier'  => 'endpoint_$n');

// a test case in my endpoint_test file
public function testParseThirdPartyResponse() {
  $phEndpoint = Phactory::create('endpoint', $options);
  $endpoint = new EndpointQuery()::create()->findPK($phEndpoint->id);

  $stub = $this->getMock('Endpoint');
  $xml = "...<target>test_target</target>...";  // sample response from third party api

  $stub->expects($this->any())
       ->method('fetchUrl')
       ->will($this->returnValue($xml));

  $result = $endpoint->parseThirdPartyResponse();
  $this->assertEquals('test_target', $result);
}

Теперь, после того, как я попробовал свой тестовый код, я вижу, что создаю фиктивный объект. с getMock, а затем никогда его не использовать. Итак, функция fetchUrlна самом деле выполняет, чего я не хочу.Но я все еще хочу иметь возможность использовать Фабрика создала объект endpoint, так как в нем есть все нужные поля заполняется из моего заводского определения.

Есть ли способ заглушить метод для существующего объекта? Так что я мог заглушить fetch_urlна объекте $endpointEndpoint, который я только что создал?

Или я все делаю неправильно; есть ли лучший способ для меня провести модульное тестирование мои функции, которые полагаются на внешние веб-запросы?

Я читал документацию PHPUnit, касающуюся «Заглушки и имитации веб-сервисов», но их пример кода для этого составляет 40 строк, не считая необходимости определять свой собственный wsdl. Мне трудно поверить, что это самый удобный способ справиться с этим, если только хорошие люди из SO не считают иначе.

Очень признателен за любую помощь, я весь день зависал на этом. Спасибо!!

7
задан goggin13 29 June 2012 в 19:53
поделиться