Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to replace methods with phpunit

Say I want to replace a method in an object that gets database from a database with one that has the data pre-populated. How would I do this?

According to https://phpunit.de/manual/current/en/test-doubles.html ...

setMethods(array $methods) can be called on the Mock Builder object to specify the methods that are to be replaced with a configurable test double. The behavior of the other methods is not changed. If you call setMethods(NULL), then no methods will be replaced.

Great. So that tells phpunit which methods I want to replace but where do I tell it what I'm replacing them with?

I found this example:

protected function createSSHMock()
{
    return $this->getMockBuilder('Net_SSH2')
        ->disableOriginalConstructor()
        ->setMethods(array('__destruct'))
        ->getMock();
}

Great - so the __destruct method is being replaced. But what is it being replaced with? I have no idea. Here's the source for that:

https://github.com/phpseclib/phpseclib/blob/master/tests/Unit/Net/SSH2Test.php

like image 671
neubert Avatar asked Nov 04 '14 14:11

neubert


People also ask

What is stub in PHPUnit?

We then use the Fluent Interface that PHPUnit provides to specify the behavior for the stub. In essence, this means that you do not need to create several temporary objects and wire them together afterwards. Instead, you chain method calls as shown in the example. This leads to more readable and “fluent” code.


1 Answers

With a method that doesn't do anything, but whose behaviour you can configure later. Although I'm not sure you fully understood how mocking works. You're not supposed to mock the class you're testing, you're supposed to mock objects on which the class being tested relies on. For example:

// class I want to test
class TaxCalculator
{
    public function calculateSalesTax(Product $product)
    {
        $price = $product->getPrice();
        return $price / 5; // whatever calculation
    }
}

// class I need to mock for testing purposes
class Product
{
    public function getPrice()   
    {
        // connect to the database, read the product and return the price
    }
}

// test
class TaxCalculatorTest extends \PHPUnit_Framework_TestCase
{
    public function testCalculateSalesTax()
    {
        // since I want to test the logic inside the calculateSalesTax method
        // I mock a product and configure the methods to return some predefined
        // values that will allow me to check that everything is okay
        $mock = $this->getMock('Product');
        $mock->method('getPrice')
             ->willReturn(10);

        $taxCalculator = new TaxCalculator();

        $this->assertEquals(2, $taxCalculator->calculateSalesTax($mock));
    }
}

Your test mocks the exact class you're trying to test, which might be a mistake, since some methods might be overridden during mocking.

like image 74
motanelu Avatar answered Oct 07 '22 22:10

motanelu