我的ProduitsControllerTest中的testRapportParams函数有问题。 当我使用变量输入url时,它会通过控制器传递else部分,这意味着变量未设置。 问题是,在核心程序中,ProduitsController运行良好。 我不明白它在我的测试中不起作用。
这是我的测试控制器的代码:
//in my ProduitsControllerTest public function testRapportParams() { //Test if the year in the url can be found $dateCompare = array(Date('Y'), Date('Y')-1, Date('Y')-2, Date('Y')-3,Date('Y')-4,Date('Y')-5,Date('Y')-6,Date('Y')-7); $produits = TableRegistry::get('Produits'); //The url called by this is : '/produits/rapport?datecompare=2015' $this->get('/produits/rapport?datecompare='.$datecompare[1]); $this->assertResponseOk(); $produitsnouveau = $this->viewVariable('produitsnouveau'); $produitssupp = $this->viewVariable('produitssupp'); //$produits->find('all')->where(['YEAR(__creation_ts) = ' => $datecompare[1]]) // ->where('supp_le_ts is NULL') // ->count() == 0 //$produits->find('all')->where(['YEAR(supp_le_ts) = ' => $datecompare[1]]) // ->count() == 2 //count($produitsnouveau) == 0 (supposed to be 0) //count($produitssupp) == 1 (supposed to be 2) $this->assertEquals($produits->find('all')->where(['YEAR(__creation_ts) = ' => $datecompare[1]])->where('supp_le_ts is NULL')->count(),count($produitsnouveau)); $this->assertEquals($produits->find('all')->where(['YEAR(supp_le_ts) = ' => $datecompare[1]])->count(),count($produitssupp)); }这是我用于测试的函数:
public function rapport() { $datecompare = array(Date('Y'), Date('Y')-1, Date('Y')-2, Date('Y')-3,Date('Y')-4,Date('Y')-5,Date('Y')-6,Date('Y')-7); $this->set('datecompare',$datecompare); //The url called is : '/produits/rapport?datecompare=2015' if(isset($_GET['datecompare'])) { $this->paginate = [ 'conditions' => [ 'Produits.supp_le_ts IS NULL', 'YEAR(Produits.__creation_ts) = ' => $_GET['datecompare'], ], 'contain' => ['Items'], 'order' => ['nom' => 'asc'] ]; $produitsnouveau = $this->paginate($this->Produits); $this->paginate = [ 'conditions' => [ 'YEAR(Produits.supp_le_ts) = ' => $_GET['datecompare'], ], 'contain' => ['Items'], 'order' => ['nom' => 'asc'] ]; $produitssupp = $this->paginate($this->Produits); debug($produitssupp); die; }else{ $this->paginate = [ 'conditions' => [ 'Produits.supp_le_ts IS NULL', 'YEAR(Produits.__creation_ts) = ' => $datecompare[0], ], 'contain' => ['Items'], 'order' => ['nom' => 'asc'] ]; $produitsnouveau = $this->paginate($this->Produits); $this->paginate = [ 'conditions' => [ 'YEAR(Produits.supp_le_ts) = ' => $datecompare[0], ], 'contain' => ['Items'], 'order' => ['nom' => 'asc'] ]; $produitssupp = $this->paginate($this->Produits); } $this->set('produitsnouveau',$produitsnouveau); $this->set('produitssupp',$produitssupp); $this->set('_serialize', ['produits']); }我想理解为什么它总是在我的测试中使用else部分,但是当我在主应用程序中使用我的浏览器时它运行良好。
I have a problem with my testRapportParams function in my ProduitsControllerTest. When I enter the url with a variable, it passes trought the controller passing by the else part, which it means the variable is not set. The thing is ,in the core program, the ProduitsController works perfectly well. I don't understand it doesn't work in my tests.
Here the code of my test controller:
//in my ProduitsControllerTest public function testRapportParams() { //Test if the year in the url can be found $dateCompare = array(Date('Y'), Date('Y')-1, Date('Y')-2, Date('Y')-3,Date('Y')-4,Date('Y')-5,Date('Y')-6,Date('Y')-7); $produits = TableRegistry::get('Produits'); //The url called by this is : '/produits/rapport?datecompare=2015' $this->get('/produits/rapport?datecompare='.$datecompare[1]); $this->assertResponseOk(); $produitsnouveau = $this->viewVariable('produitsnouveau'); $produitssupp = $this->viewVariable('produitssupp'); //$produits->find('all')->where(['YEAR(__creation_ts) = ' => $datecompare[1]]) // ->where('supp_le_ts is NULL') // ->count() == 0 //$produits->find('all')->where(['YEAR(supp_le_ts) = ' => $datecompare[1]]) // ->count() == 2 //count($produitsnouveau) == 0 (supposed to be 0) //count($produitssupp) == 1 (supposed to be 2) $this->assertEquals($produits->find('all')->where(['YEAR(__creation_ts) = ' => $datecompare[1]])->where('supp_le_ts is NULL')->count(),count($produitsnouveau)); $this->assertEquals($produits->find('all')->where(['YEAR(supp_le_ts) = ' => $datecompare[1]])->count(),count($produitssupp)); }Here is the function I use for the test :
public function rapport() { $datecompare = array(Date('Y'), Date('Y')-1, Date('Y')-2, Date('Y')-3,Date('Y')-4,Date('Y')-5,Date('Y')-6,Date('Y')-7); $this->set('datecompare',$datecompare); //The url called is : '/produits/rapport?datecompare=2015' if(isset($_GET['datecompare'])) { $this->paginate = [ 'conditions' => [ 'Produits.supp_le_ts IS NULL', 'YEAR(Produits.__creation_ts) = ' => $_GET['datecompare'], ], 'contain' => ['Items'], 'order' => ['nom' => 'asc'] ]; $produitsnouveau = $this->paginate($this->Produits); $this->paginate = [ 'conditions' => [ 'YEAR(Produits.supp_le_ts) = ' => $_GET['datecompare'], ], 'contain' => ['Items'], 'order' => ['nom' => 'asc'] ]; $produitssupp = $this->paginate($this->Produits); debug($produitssupp); die; }else{ $this->paginate = [ 'conditions' => [ 'Produits.supp_le_ts IS NULL', 'YEAR(Produits.__creation_ts) = ' => $datecompare[0], ], 'contain' => ['Items'], 'order' => ['nom' => 'asc'] ]; $produitsnouveau = $this->paginate($this->Produits); $this->paginate = [ 'conditions' => [ 'YEAR(Produits.supp_le_ts) = ' => $datecompare[0], ], 'contain' => ['Items'], 'order' => ['nom' => 'asc'] ]; $produitssupp = $this->paginate($this->Produits); } $this->set('produitsnouveau',$produitsnouveau); $this->set('produitssupp',$produitssupp); $this->set('_serialize', ['produits']); }I would like to understand why it always pass in the else part when used in my test but it work well when im using my browser in the main app.
最满意答案
这样做是因为你没有使用正确的CakePHP技术来检索请求数据,即\Cake\Network\Request对象,特别是Request::query() ,就像
$datecompare = $this->request->query('datecompare'); if ($datecompare !== null) { // ...集成测试用例只是模拟请求,它不会调度真实的,因此, $_GET将不会被填充,因为它会污染全局状态,而是数据将直接设置为请求对象。
看到
Source> \ Cake \ TestSuite \ IntegrationTestCase :: _ buildRequest() 食谱>请求和响应对象 Cookbook>请求和响应对象>请求>查询字符串参数It does so because you are not using the proper CakePHP techniques for retrieving request data, that is, the \Cake\Network\Request object, specifically Request::query(), like
$datecompare = $this->request->query('datecompare'); if ($datecompare !== null) { // ...The integration test case just simulates requests, it doesn't dispatch real ones, and thus, $_GET will not be populated as it would pollute the global state, instead the data will be set directly to the request object.
See
Source > \Cake\TestSuite\IntegrationTestCase::_buildRequest() Cookbook > Request & Response Objects Cookbook > Request & Response Objects > Request > Query String Parameters更多推荐
发布评论