views:

258

answers:

2

To test inserting/update of a row, I've written a test to simulate a post, to check that it redirects, and to check that the newly inserted/updated text is on the page. The code works, but not the test - can you tell me why it's wrong?

public function testEditProduct() {
    $request = $this->getRequest();
    $request->setMethod('POST');
    $request->setPost(array(
     'id'=>'1',
     'title'=>'Test Product 1a'
    ));
    $this->dispatch('/product/edit/id/1');
    $this->assertRedirectTo('/');
    $this->assertQueryContentContains('a', 'Test Product 1a');
}
public function testAddProduct() {
    $request = $this->getRequest();
    $request->setMethod('POST');
    $request->setPost(array(
     'title'=>'Test Product 3'
    ));
    $this->dispatch('/product/add/');
    $this->assertRedirectTo('/');
    $this->assertQueryContentContains('a', 'Test Product 3');
}

The following tests both work, asserting that the index page with an ID parameter contains the appropriate text, and that after deleting a product that product's title is no longer displayed on the page.

public function testIndexPageListsProducts() {
    $this->dispatch('/product/index/id/1');
    $this->assertQueryContentContains('h1', 'Test Product 1');
}

public function testDeleteProduct() {
    $request = $this->getRequest();
    $request->setMethod('POST');
    $this->dispatch('/product/delete/id/2');
    $this->assertRedirectTo('/');
    $this->assertNotQueryContentContains('a', 'Test Product 2');
}
+2  A: 

In your first test, change

$this->assertRedirectTo('/');
$this->assertQueryContentContains('a', 'Test Product 3');

to

$this->assertRedirectTo('/');

$this->resetRequest();
$this->resetResponse();

$this->disptach('/');
$this->assertQueryContentContains('a', 'Test Product 3');

If I'm correct, the unit testing framework does not execute redirects. It keeps track of which redirects were requested, but does not actually do them.

So in your code, you're checking for the presence of 'Test Product 3' on the edit view/action, and that test fails of course. You should first request the index, and then do the test.

bertbalcaen
A: 

Hi, thanks for your help. I found that $this->resetRequest(); and $this->resetResponse(); threw errors, but I checked the method summary for Zend_Test_PHPUnit_ControllerTestCase and found $this->reset(); The linked page does list the methods you mention, but they're listed differently.

$this-reset(); alone also threw an error (No default module defined for this application), but I found that if I called $this->bootstrap(); afterwards the tests passed. Is this a valid solution? For clarify, my test code is now:

public function testEditProduct() {
 $request = $this->getRequest();
 $request->setMethod('POST');
 $request->setPost(array(
  'id'=>'1',
  'title'=>'Test Product 1a'
 ));
 $this->dispatch('/product/edit/id/1');
 $this->assertRedirectTo('/');

 $this->reset();
 $this->bootstrap();
 $this->dispatch('/');
 $this->assertQueryContentContains('a', 'Test Product 1a');
}
public function testAddProduct() {
 $request = $this->getRequest();
 $request->setMethod('POST');
 $request->setPost(array(
  'title'=>'Test Product 3'
 ));
  $this->dispatch('/product/add/');
 $this->assertRedirectTo('/');

 $this->reset();
 $this->bootstrap();
 $this->dispatch('/');
 $this->assertQueryContentContains('a', 'Test Product 3');
}
Iain