Издевательство над пользовательским классом с помощью Mockery в Laravel 4

Используя Laravel 4.2, у меня есть собственный класс TestyClass в /app/libraries.

Используя Mockery и PHPUnit, я пытаюсь издеваться над этим классом, но мой Mock, похоже, не регистрируется.

Когда я запускаю тест, я получаю Mockery\Exception\InvalidCountException: Method testymethod() from Mockery_0_TestyClass should be called exactly 1 times but called 0 times.

Мой Контроллер, который я тестирую, работает TestyClass::testymethod();, а Log :: info внутри testymethod() работает правильно.

Что мне не хватает для регистрации Mock пользовательского класса в Laravel 4.2?

$mock = Mockery::mock('TestyClass');
$mock->shouldReceive('testymethod')->once();

TestyClass:

class TestyClass {
    public static function testymethod() {
        Log::info('----=-=-=-=--=in heyhey!@!!=-=-=-=-=-=-=-12312312312312341');
        return true;
    }   
}

person Luke Shaheen    schedule 09.10.2014    source источник


Ответы (3)


Этот код:

$mock = Mockery::mock('TestyClass');

Создает новый класс, который расширяет TestyClass, добавляя поведение, необходимое для имитации и т. Д., Затем создает его экземпляр и возвращает его, поэтому $ mock является экземпляром Mockery_0_TestyClass

Затем вы насмехаетесь о том, что ожидаете, что экземпляр получит вызов testymethod, но на самом деле вы делаете статический вызов метода класса TestyClass. Вы можете сделать это с насмешкой, но это не очень хорошо, я бы не рекомендовал это делать, и вы, вероятно, захотите запускать свои тесты с изоляцией процесса.

$mock = Mockery::mock('alias:TestyClass');
person Dave Marshall    schedule 09.10.2014
comment
Да, как вы сказали, что это не очень хорошо, alias работал с моим фиктивным TestyClass, но применительно к моему настоящему и обширному Lib классу он сломался: PHP Fatal error: Call to a member function __call() on a non-object in /Users/lukeshaheen/Dropbox/WWW/Phone2Action 2.0/vendor/mockery/mockery/library/Mockery/Loader/EvalLoader.php(16) : eval()'d code on line 633. - person Luke Shaheen; 10.10.2014

Вы звоните своему контроллеру? Есть разница в тестировании метода класса и тестировании контроллера. Если вы тестируете контроллер, попробуйте использовать $this->call - example;

class TestyClassTest extends TestCase {

  public function setUp()
  {
    $this->mock = $this->mock('TestyClass');
  }

  /* Move method to TestCase.php */
  public function mock($class)
  {
    $mock = Mockery::mock($class);
    $this->app->instance($class, $mock);
    return $mock;
  }

  /* Move method to TestCase.php */
  public function tearDown()
  {
    Mockery::close();
  }

  public function testIfTestyControllerRunsTestyMethodAndReturnsOk()
  {
    // Step 3. Arrange
    // Last we arrange our test

    $this->mock->shouldReceive('testymethod')->once();

    // Step 2. Act
    // Then we write how we the results will be asserted.
    // The route should correspond with the controller executing the class method.
    // Eg. TestyMethodController@test; return $this->class->testymethod()

    **$this->call('GET', 'TestyController@test');**

    // Step 1. Assert
    // Start by writing the results we expect;
    // If the controller issues no Exceptions we should get a response header status 200.

    $this->assertResponseOk();
  }
}

По сути, $ mock-> shouldReceive устанавливает слушателя на фиктивный объект, он ожидает запуска метода - если он запущен, все в порядке, иначе вы получите InvalidCountException.

Надеюсь, что это поможет, хорошего дня.

person dojs    schedule 29.10.2014

У меня возникла аналогичная проблема: класс не был распознан. Попробуйте использовать метод __construct для его инициализации. У меня это сработало. (Не сработала установка в методе setUp).

public function __construct()
{
    $this->mock = Mockery::mock('TestyClass');
}

а затем просто вызовите тестовый метод:

$this->mock->shouldReceive('testymethod')->once();
person Angel M.    schedule 23.01.2015