mardi 2 octobre 2018

CakePHP3: Mock methods in integration tests?

I'm new to unit / integration testing and I want to do an integration test of my controller which looks simplified like this:

// ItemsController.php
public function edit() {

    // some edited item
    $itemEntity

    // some keywords
    $keywordEntities = [keyword1, keyword2, ...]

    // save item entity
    if (!$this->Items->save($itemEntity)) {
        // do some error handling
    }

    // add/replace item's keywords 
    if (!$this->Items->Keywords->replaceLinks($itemEntity, $keywordEntities)) {
       // do some error handling
    }
}

I have the models Items and Keywords where Items belongsToMany Keywords. I want to test the error handling parts of the controller. So I have to mock the save() and replaceLinks() methods that they will return false.

My integration test looks like this:

// ItemsControllerTest.php
public function testEdit() {

    // mock save method
    $model = $this->getMockForModel('Items', ['save']);
    $model->expects($this->any())->method('save')->will($this->returnValue(false));

    // call the edit method of the controller and do some assertions...

}

This is working fine for the save() method. But it is not working for the replaceLinks() method. Obviously because it is not part of the model.

I've also tried something like this:

$method = $this->getMockBuilder(BelongsToMany::class)
    ->setConstructorArgs([
        'Keywords', [
            'foreignKey' => 'item_id',
            'targetForeignKey' => 'keyword_id',
            'joinTable' => 'items_keywords'
        ]
    ])
    ->setMethods(['replaceLinks'])
    ->getMock();

$method->expects($this->any())->method('replaceLinks')->will($this->returnValue(false));

But this is also not working. Any hints for mocking the replaceLinks() method?

Aucun commentaire:

Enregistrer un commentaire