繁体   English   中英

ci_phpunit_test:有关使用查询进行双重测试所需的帮助

[英]ci_phpunit_test: Help needed about test double with queries

我正在学习使用CodeIgniter进行单元测试,并且想问一些关于使用Mocks类测试查询的问题。

我尝试使用get_news_all()方法实现以下类News_model,该方法返回表'news'中的所有新闻数据,而get_news仅返回相同标题和文本字段。

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;
}

在我尝试为测试方法get_news_all()构建News_model_with_mocks_test并在这种情况下,测试运行正常:

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);
}

}

但是我不知道如何对方法get_news()进行测试,我这样尝试过:

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引发以下异常:

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

我不知道如何使用选择查询进行双重测试! 预先感谢您的回答。

这些天我阅读了更多文档,并且我知道这对我来说是关于Mocks使用的误解。 换句话说,我们必须定义方法和返回期望的值,并将它们注入到原始类中。 这是我上面编写的News_model类的get_users方法:

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

我们只是希望get()方法将返回一个结果数组,该数组仅包含每个记录的标题和文本字段:

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 = [
            [
                    "title" => "News test",
                    "text" => "News text",
            ],
            [
                    "title" => "News2",
                    "text" => "Testo 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')->willReturn($db_result);
    $this->obj->db=$db;
    $result=$this->obj->get_news();
    $this->assertEquals($result_array,$result);
}
}

我希望这种解决方案可以帮助可能会有同样疑问的人!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM