2015-08-19 1 views
2

я не могу получить Насмешка создать простой манекен:Насмешка: BadMethodCallException: Method Mockery_0_Foo :: бар() не существует на этом макете объекта

<?php 
require_once '../vendor/autoload.php'; // composer autoload mockery 

class Foo { 
    private $required; 
    public function __construct($required){ 
     $this->required = $required; 
    } 
    public function bar(){ 
     // do stuff with $this->required 
    } 
} 

class FooTest extends PHPUnit_Framework_TestCase { 
    public function testBar(){ 
     $mock = \Mockery::mock('\Foo'); 
     $mock->bar(); 
    } 
} 

Запуск этого теста PHPUnit дает ошибку:

BadMethodCallException: Method Mockery_0_Foo::bar() does not exist on this mock object 

Что я делаю неправильно?

ответ

1

я должен явно указать, какие методы макет делает патрубки:

class FooTest extends PHPUnit_Framework_TestCase { 
    public function testBar(){ 
     $mock = \Mockery::mock('Foo'); 
     $mock->shouldReceive('bar'); 
     $mock->bar(); 
    } 
} 

Мне интересно, если есть способ обойти это, что-то, либо:

  1. неявно перехватывает все вызовы методов которые определены в Foo, или
  2. неявно улавливает все вызовы методов, независимо от того, определены они или нет в Foo
3

Если вы хотите выполнить тестирование модуля php на классе «Foo» и издевается над «Обязательным» объектом. Просто сделайте это, как показано ниже:

class Foo { 
    private $required; 
    public function __construct(\Required $required){ 
     $this->required = $required; 
    } 
    public function bar(){ 
     return $this->required->getTextFromBarTable(); 
    } 
} 

class FooTest extends PHPUnit_Framework_TestCase { 
    public function testBar(){ 
     $mock = \Mockery::mock('\Required'); // Dummy, There are no properties or methods. 

     /** 
     * Stub "getTextFromBarTable" method of \Required class 
     * and fakes response by returning "return this text". 
     */ 
     $mock->shouldReceive('getTextFromBarTable') 
      ->andReturn('return this text'); 

     // create "Foo" Object by using $mock instead of actual "\Required" Object. 
     $foo = new Foo($mock); 
     $response = $foo->bar(); 

     $this->assertEqual('return this text', $response); 
    } 
} 

Вы не должны заглушать или издеваться над классом, над которым вы хотите выполнить модульное тестирование. Просто сделайте это в классе зависимости, например «\ Required».


мы делаем STUB или MOCK, чтобы отделить ВНЕШНЮЮ логику, которая может повлиять на внутреннюю логику метода, который мы собираемся протестировать. В этом случае я предположил, что \ Required класс имеет метод getTextFromBarTable, и этот метод будет подключаться и получать поле «текст» из базы данных. Метод «testBar» будет разорван, если наша база данных не имеет текстового поля. Чтобы избавиться от внешних проблем, я сделал заглушку на «\ Required», и каждый раз я использую метод getTextFromBarTable. Он всегда вернет мне «вернуть этот текст».

Смежные вопросы