How would you test this code? (Phpunit)

How would you test the following code with phpUnit?

class Product {

    protected $id = null;

    public function __construct($id) {
        $this->id = $id;
    }

    public function getDescription($language_id) {
        $db_query = mysql_query("SELECT * FROM products_description WHERE products_id = " . (int) $this->id . " AND language = " . (int) $language_id);
        return mysql_fetch_array($db_query);
    }

}


$product = new Product(1);
$product->getDescription(1); // Test this

I am currently testing this as follows:

public function testShouldGetProductsDescription() {
    $product = new Product(1);
    $description = $product->getDescription(1);
    $expected_description = array(
        'name' => 'car',
        'short_text' => 'this is a car',
        'long_text' => 'longer description for the car'
    );
    $this->assertEquals($description, $expected_description);
}

But this does not seem to be a good solution for me. (This code is just an example and may not work correctly)

+3
source share
3 answers

In simple cases, especially with such a database connection, I usually just use stub objects to drown out the database calls. Then simply write the test as follows:

 public function productFixture($id)
 {  
    $constructor_arg = $id;

    //Array of methods to stub out
    $stubbed_method = array('getDescription'); 

    //Create a mock for the Product class.
    $product = $this->getMock('Product', $stubbed_method, $constructor_arg);

    //Stub out expected results
    $expected_description = array(
        'name'       => 'car',
        'short_text' => 'this is a car',
        'long_text'  => 'longer description for the car'
    );

    //Configure the stub method and its return value
    $product->expects($this->any())
            ->method('getDescription')
            ->will($this->returnValue($expected_description));

    return $product;
}

public function testShouldGetProductsDescription()
{
    $product = $this->productFixture(1);
    $description = $product->getDescription(1);

    $this->assertNotNull($description);

    //You could test the description using assertEquals
    //but I find just testing the field names is less brittle
    $this->assertArrayHasKey('name', $description);
    $this->assertArrayHasKey('short_text', $description);
    $this->assertArrayHasKey('long_text', $description);
}

code>

Learn more about Stubs / Mocks and PHPUnit: PHPUnit Manual: Test Doubles

+2
source

, , , , , - .

:

+2

Your product class is closely related to the database, as it directly calls mysql_query. If you easily bind it to a database, for example using a database object or a ProductStore object, you can test the Product class without actually using the database.

+1
source

Source: https://habr.com/ru/post/1766153/


All Articles