jeudi 30 juin 2016

ci_phpunit_test: Help needed about test double with queries

i'm learning about unit testing with CodeIgniter and i would to ask some questions about testing queries with Mocks class.

I tried to implement the following class News_model with the method get_news_all() that returns all news data from table 'news' and get_news returns only title and text fields from the same.

class News_model extends CI_Model
{
public function __construct(){
    $this->load->database();
}

public function get_news_all()
{
    $query=$this->db->get('news');
    $result=$query->result_array();
    return $result;
}

public function get_news()
{
    $this->db->select('title, text');
    $this->db->from('news');
    $query=$this->db->get();
    $result=$query->result_array();
    return $result;
}

After i tried to build a News_model_with_mocks_test for testing method get_news_all() and in this case test runs fine:

class News_model_with_mocks_test extends TestCase
{
public function setUp()
{
    $this->resetInstance();
    $loader=$this->getMockBuilder('CI_Loader')->setMethods(['database'])->getMock();
    $loader->method('database')->willReturn($loader);
    $this->CI->load=$loader;
    if(!class_exists('CI_DB', false))
    {
        eval('class CI_DB extends CI_DB_query_builder {}');
    }
    $this->obj=new News_model();
}

public function test_1()
{
    $result_array = [
            [
                    "id" => "1",
                    "title" => "News",
                    "slug" => "news",
                    "text" => "News",
            ],
            [
                    "id" => "2",
                    "title" => "News2",
                    "slug" => "news2",
                    "text" => "News2",
            ],
    ];
    $db_result=$this->getMockBuilder('CI_DB_result')->disableOriginalConstructor()->getMock();
    $db_result->method('result_array')->willReturn($result_array);
    $db = $this->getMockBuilder('CI_DB')->disableOriginalConstructor()->getMock();
    $db->expects($this->once())->method('get')->with('news')->willReturn($db_result);
    $this->obj->db=$db;
    $result=$this->obj->get_news_all();
    $this->assertEquals($result_array,$result);
}

}

But i don't know how to do tests for the method get_news(), i tried something as this:

public function test_1()
{
    $result_array2 = [
            [
                    "title" => "News",
                    "text" => "News",
            ],
            [
                    "title" => "News2",
                    "text" => "News2",
            ],
    ];
    $db_result=$this->getMockBuilder('CI_DB_result')->disableOriginalConstructor()->getMock();
    $db_result->method('result_array')->willReturn($result_array2);
    $db = $this->getMockBuilder('CI_DB')->disableOriginalConstructor()->getMock();
    $db->expects($this->once())->method('query')->with('select title,text from news')->willReturn($db_result);
    $this->obj->db=$db;
    $result=$this->obj->get_news();
    $this->assertEquals($result_array2,$result);
}

phpunit thows the following exception:

PHP Fatal error:  Call to a member function result_array() on a non-   object in /opt/lampp/htdocs/codeigniter/application/models/Users_model.php on line 21

I don't know how to test double with select queries! Thank you in advance for your answers.

Aucun commentaire:

Enregistrer un commentaire