我正在学习使用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
我不知道如何使用select查询测试双倍!提前感谢您的回答。
答案 0 :(得分:0)
我在这些日子里阅读了更多文档,我明白这是对我使用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);
}
}
我希望这个解决方案可以帮助那些有同样疑虑的人!