PHPUnit和Zend框架的assertRedirectTo()问题

3

我在一个测试中使用assertRedirectTo()时遇到了问题,以下是我使用的代码:

public function testLoggedInIndexAction() {
  $this->dispatch('/');
  $this->assertController('index');
  $this->resetResponse();
  $this->request->setPost(array(
   'type' => 'login',
   'username' => 'root',
   'password' => 'asdasd',
  ));
  $this->request->setMethod('POST');
  $this->dispatch('/');
  $this->assertRedirectTo('/feed/');
}

您可以通过 / (index.php/) 登录系统并提交帖子详情,接着会自动重定向到 /feed/ (index.php/feed/) 页面。我提供的信息是正确的,并且应该可以正常工作,但是我遇到了一个问题,PHPUnit 表明我的信息是不正确的:

There was 1 failure:

1) IndexControllerTest::testLoggedInIndexAction
Failed asserting response redirects to "/feed/"

/home/public_html/mashhr/library/Zend/Test/PHPUnit/Constraint/Redirect.php:190
/home/public_html/mashhr/library/Zend/Test/PHPUnit/ControllerTestCase.php:701
/home/public_html/mashhr/tests/application/controllers/UserControllerTest.php:36

在你的indexController中,feed是一个操作吗?如果是,请尝试:$this->assertRedirectTo('/index/feed'); - opHASnoNAME
不,这是完全不同的控制器。 - Prisoner
5个回答

3

@poelinca: 不,这只是Zend_Test在注册重定向时不可靠的情况(即使已经正确调用!)

在他的情况下,真正的应用程序无疑会正确地重定向用户,但Zend_Test环境在注册正确调用的重定向时遇到了问题。我能想到的最好的回应是省略任何失败的assertRedirect,而这些assertRedirect实际上在应用程序中是有效的。

这不是最理想的情况,但除非你准备深入研究Zend代码以查看问题所在,否则这可能是效率最高的选择。这是导致单元测试声名狼藉的原因之一:必须更改代码才能通过实际已经工作的测试。

请参见http://framework.zend.com/issues/browse/ZF-7496,标题具有误导性:该问题涉及所有重定向,特别是那些必须设置标头并退出而不是分派原始控制器的重定向。

由于某种原因,这种行为导致重定向并不总是失败,而是变得极其不可靠!如果有人知道解决此问题的更好方法(这是普遍存在的问题,可能与OP的代码无关),请告诉我们。


另外,我想补充一点,如果您在控制器init()中完成所有重定向 - 例如,您使用自己的基类包装Zend的Controller Action类,并以这种方式完成所有操作: (在init()中) if(cond) { return $this->redirector->gotoSimple('logout','login','default'); } 如果您的应用程序正常工作,则测试应该通过,如果不正常,则应该失败,这是预期的结果。 - RiverC

3

我在遇到相同问题时发现了这个问题。最终我做了以下操作:

$this->assertRedirect();
$responseHeaders = $this->response->getHeaders();
$this->assertTrue(count($responseHeaders) != 0);
$this->assertArrayHasKey('value', $responseHeaders[0]);
// in my case I'm redirecting to another module
$this->assertEquals('/module/controller/action', $responseHeaders[0]['value']);

1

我已经在http://zend-framework-community.634137.n4.nabble.com/Zend-Test-failing-on-AssertRedirectTo-td3325845.html#a4451217中回答了这个问题。

我也遇到了同样的问题... 一种可能的断言方式是在

但问题仍然存在.. 我的例子是(如果手动完成,实际上可以工作):

// controller modules/picking/orders/product
$orderId = $this->_getParam('oId');    
if (empty($orderId)) {
    return $this->_redirect('picking/orders/browse/invalid/empty');
}

// test
$this->dispatch('picking/orders/product');
$this->assertRedirect(); // ok
$this->assertRedirectTo('picking/orders/browse'); // error
$this->assertRedirectTo('picking/orders/browse/invalid/empty'); // error

找到错误后!


实际上,按照上面的例子,我发现我的示例中字符串比较存在错误:

'.../public//picking/orders/browse/invalid/empty'
'.../public/picking/orders/browse/invalid/empty'

...修复前置斜杠即可解决问题!;)


0

所以如果我理解正确,你写了一个失败的测试(我认为这很完美)。

为了使测试通过,您需要调试应用程序并查看问题所在,在这种情况下,您需要查看实际重定向(或甚至表单发送的帖子字段),也许还要检查路由。我猜除非您在索引控制器/表单/视图和Feed控制器中发布代码,否则没有人能回答您的问题。


1
据我所知,测试表单的正确方式是使用模拟和存根。在此处查看(他正在测试从isValid true/false重定向的表单)http://avnetlabs.com/zend-framework/tdd-with-zend-framework-mocks-and-stubs - Poelinca Dorin

0

为了以后参考,我今天遇到了这个问题,它是由于Url类无法构建有效的URL(我传递了错误的参数),但没有向PHPUnit报告错误(可能是因为PHPUnit掩盖了错误)。

纠正URL参数可以修复URL,并使断言正确。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接