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
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With