Nasıl PHPUnit MockObjects bir parametreye dayalı differernt değerleri döndürmek için alabilirim?

9 Cevap php

Ben ne olursa olsun onun argümanları "dönüş değeri" döndüren bir PHPUnit davalarını nesne var:

// From inside a test...
$mock = $this->getMock('myObject', 'methodToMock');
$mock->expects($this->any))
     ->method('methodToMock')
     ->will($this->returnValue('return value'));

Ne yapmam mümkün istiyorum sahte yönteme geçirilen argümanlara dayalı farklı bir değer döndürür olduğunu. Ben böyle bir şey denedim:

$mock = $this->getMock('myObject', 'methodToMock');
// methodToMock('one')
$mock->expects($this->any))
     ->method('methodToMock')
     ->with($this->equalTo('one'))
     ->will($this->returnValue('method called with argument "one"'));
// methodToMock('two')
$mock->expects($this->any))
     ->method('methodToMock')
     ->with($this->equalTo('two'))
     ->will($this->returnValue('method called with argument "two"'));

Ama bu sahte bir argüman "iki" ile adlandırılan değilse PHPUnit şikayet olur, bu yüzden methodToMock ('iki') tanımı ilk tanımını yazar olduğunu varsayalım.

Benim soru yani: onun argümanlara dayalı farklı bir değer döndürmek için bir PHPUnit davalarını nesne almak için herhangi bir yolu var mı? Ve eğer öyleyse, nasıl?

Şimdiden teşekkürler!

9 Cevap

Bir geri kullanın. örneğin (Düz PHPUnit belgelere):

<?php
class StubTest extends PHPUnit_Framework_TestCase
{
    public function testReturnCallbackStub()
    {
        $stub = $this->getMock(
          'SomeClass', array('doSomething')
        );

        $stub->expects($this->any())
             ->method('doSomething')
             ->will($this->returnCallback('callback'));

        // $stub->doSomething() returns callback(...)
    }
}

function callback() {
    $args = func_get_args();
    // ...
}
?>

Geri arama istediğiniz ne olursa olsun işlem yapmak () ve uygun olarak $ args dayanarak sonuca dönmek.

Muhtemelen bir OOP moda bir geri arama yapmak isterim:

<?php
class StubTest extends PHPUnit_Framework_TestCase
{
    public function testReturnAction()
    {
        $object = $this->getMock('class_name', array('method_to_mock'));
        $object->expects($this->any())
            ->method('method_to_mock')
            ->will($this->returnCallback(array($this, 'returnCallback'));

        $object->returnAction('param1');
        // assert what param1 should return here

        $object->returnAction('param2');
        // assert what param2 should return here
    }

    public function returnCallback()
    {
        $args = func_get_args();

        // process $args[0] here and return the data you want to mock
        return 'The parameter was ' . $args[0];
    }
}
?>

Ben benzer bir sorun vardı (biraz farklı olmasına rağmen ... Ben argümanlara dayalı farklı dönüş değeri gerek yoktu, ama argümanlar 2 takım aynı işleve geçirilen ediliyordu sağlamak için test etmek zorunda). Böyle bir şey kullanarak tökezledi:

$mock = $this->getMock();
$mock->expects($this->at(0))->method('foo')->with(...)->will($this->returnValue(...));
$mock->expects($this->at(1))->method('foo')->with(...)->will($this->returnValue(...));

Bu foo () için 2 aramaların sırası bilinen gerektirir, ancak pratikte bu muhtemelen too kötü değil, çünkü mükemmel değil.

Son phpunit Dokümanlar: "Bazen bir söndürdü yöntemi, argümanların önceden tanımlanmış bir listeden bağlı olarak farklı değerler dönmelidir Sen returnValueMap() return değerleri karşılık gelen argümanlar ilişkilendiren bir harita oluşturmak için kullanabilirsiniz.."

$mock->expects($this->any())
    ->method('getConfigValue')
    ->will(
        $this->returnValueMap(
            array(
                array('firstparam', 'secondparam', 'retval'),
                array('modes', 'foo', array('Array', 'of', 'modes'))
            )
        )
    );

Eğer böyle bir şey mi demek istiyorsun?

public function TestSomeCondition($condition){
  $mockObj = $this->getMockObject();
  $mockObj->setReturnValue('yourMethod',$condition);
}

Ben (PHPUnit için hakkında şaşırtıcı derecede az bilgi var) de işe olamazdı benzer bir sorun vardı. Bilinen giriş ve bilinen çıkış - Benim durumumda, ben sadece her test ayrı bir test yaptı. Ben sadece belirli bir test için belirli bir ihtiyaç ve böylece ben testleri ayrılır, bir jack-of-all-esnaf davalarını nesne yapmak gerek yoktu ve ayrı olarak benim kod bireysel yönlerini test edebilirsiniz fark birimi. Ben bu sizin ya da değil geçerli olabilir emin değilim, ama bu aşağı test için gereken ne var.

Ayrıca aşağıdaki gibi argüman dönebilirsiniz:

$stub = $this->getMock(
  'SomeClass', array('doSomething')
);

$stub->expects($this->any())
     ->method('doSomething')
     ->will($this->returnArgument(0));

Bu sizden tam olarak ne değildir, ancak bazı durumlarda yardımcı olabilir:

$mock->expects($this->any))
 ->method('methodToMock')
 ->will($this->onConsecutiveCalls('one', 'two'));

onConsecutiveCalls - belirtilen sırayla değerlerin bir listesini döndürür

Deneyin:

->with($this->equalTo('one'),$this->equalTo('two))->will($this->returnValue('return value'));