PHPUNIT Mocking метод для принятия любого параметра - PullRequest
0 голосов
/ 31 мая 2019

Я использую simple-phpunit из phpunit / phpunit-bridge здесь и с Symfony.

У меня есть класс A, который я хочу протестировать, который использует метод класса Bв нем.

Во время насмешек над B и его методом я понимаю, что он вызывается несколько раз и с несколькими параметрами: именем класса и целым числом.Я использую returnValueMap () для этого, но у меня есть проблема: PHPUNIT, кажется, требует, чтобы я точно установил параметры, их точное значение, когда метод должен быть вызван.Я могу установить имя класса (для них есть заданное возможное число, поэтому я могу установить их вручную), но данное целое число является произвольным (и метод вызывается в цикле), поэтому я не могу установить его точно.

Можно ли сказать PHPUNIT принять какой-либо параметр для этой функции?Как и метод anyParameter () (который я не нашел после очистки файла TestCase).

Если я установил для параметра Integer фиксированное значение в тесте и методе класса, тест проходил (но, конечно,Я не могу установить Integer как фиксированное значение в методе класса).

class ToBeTested{
     public $objectB;
     public function functionToTest($dataList){
        ......
        $objectB=new ObjectB();
        foreach($dataList as $data){
            $className=$data['className'];
            $integerNeeded=$data['integer'];
            //Here if $inetegerNeeded is not the exact value set in the Mock
            //$result will be null
            $result=$this->objectB->doSomething($className,$integerNeeded);
            if($result == null) throw new \Excpetion(" Object is null");
        }
        .....
     }
}

class UnitTest extends TestCase{
       /**
         $generatedDataList comes from a DataProvider 
          with some varied and exotic data close to real use cases
       **/
       public function testFunction($generatedDataList)
       {
           $mockOfObjectB= $this->getMockBuilder(ObjectB::class)
                 ->getMock();
          /**
      Here I'd like to use $this->anyParameter() or something that'd work that      way 
      If I set this to a fixed value here and in the functionToTest() method it   passes 
          **/
           $anyInteger=-1;  
           $dataReferenceMap= [
              ['ClassNameA',$anyInteger,new MockObject()],
              ['ClassNameB',$anyInteger,new MockObject()],
              ['ClassNameC',$anyInteger,new MockObject()],
           ];
           $mockOfObjectB
            ->expects($this->any())
            ->method('doSomething')
            ->will($this->returnValueMap($dataReferenceMap));
            $objectToTest = new ToBeTested();
            $objectToTest->objectB=$mockOfObjectB;

            //DO THE TESTING - will because of the parameter Fail 
            $objectToTest->functionToTest($generatedDataList);
          }
    }
}

Могу ли я быть также неправым returnValueMap()?

Это довольно ново для меня, и я думаю, что документы на нем довольно скудны и не очень хорошо объясняют, как его использовать.

1 Ответ

0 голосов
/ 01 июня 2019

Я бы пошел с willReturnCallback. Вот пример (проверено с помощью phpunit 8.1)

<?php

declare(strict_types = 1);

use PHPUnit\Framework\TestCase;

final class SomeTest extends TestCase
{
    public function testSome()
    {
        $mock = $this
            ->getMockBuilder(\stdClass::class)
            ->setMethods(['doSomething'])
            ->getMock();
        $mock->method('doSomething')
            ->willReturnCallback(
                function (string $classname, int $int) {
                    $map = [
                    'ClassNameA' => 123,
                    'ClassNameB' => 345,
                    // ...
                    ];
                    return $map[$classname];
                }
            );
        $this->assertSame(123, $mock->doSomething('ClassNameA', 1));
        $this->assertSame(123, $mock->doSomething('ClassNameA', 1111111));
        $this->assertSame(345, $mock->doSomething('ClassNameB', 13456));
        $this->assertSame(345, $mock->doSomething('ClassNameB', 999999));
    }
}

Это ярлык для ->will($this->returnCallback(...)). Документ

...