【问题标题】:throw new exception laravel doesnt work in expectException PHP unit抛出新异常 laravel 在expectEexception PHPunit 中不起作用
【发布时间】:2021-04-16 17:21:49
【问题描述】:

程序中正确抛出异常,但测试未检测到。为什么??

public function null_user_send()
{
    $message = 'Hi';
    $response = $this->post(route('dialogSend'), ['to' => -1, 'message' => $message]);
    $this->assertDatabaseMissing('messages', ['to' => -1, 'message' => $message]);
    $this->expectException(Exception::class);
    $response->assertStatus(500);
}

邮件控制器:

/** @throws \Exception */
public function dialogSend(Request $request)
{
    $handler = app(MailHandler::class);
    if ($request->input('to') <= 0) {
        throw new \Exception('Параметр "to" имел отрицательное значение', 500);
    }
    ...
}

测试响应:“断言抛出“异常”类型的异常失败。 什么类别的例外都没有关系,没有任何作用。请帮忙

【问题讨论】:

    标签: php laravel unit-testing exception


    【解决方案1】:

    检查你正在测试的异常的命名空间

    $this->expectException(Exception::class);
    

    应该是

    $this->expectException(\Exception::class);
    

    这是因为您的测试本身位于其自己的命名空间中(取决于测试的类型)。您的测试实际上可能是看到的是

    $this->expectException(\Tests\Exception::class);
    

    它当然永远不会被抛出,因为它不存在。

    您无法诊断此问题的原因之一是您的测试性质。那里有几件事,虽然不是完全错误,但会使您的测试更难确定问题的原因。

    1. 你试图一次测试太多。将每个关注点分离到自己的测试中,以便您可以首先确定数据库是否为空,然后如果它抛出异常,然后如果它返回 500 错误。您实际上是在此处测试应用程序的三个不同方面。

      public function null_user_send()
      {
          // Arrange
          $message = 'Hi';
      
          // Act
          $response = $this->post(route('dialogSend'), ['to' => -1, 'message' => $message]);
      
          // Assert
          $this->assertDatabaseMissing('messages', ['to' => -1, 'message' => $message]);
      }
      
      public function does_an_exception()
      {
          // Arrange, Act
          ...
          // Assert
          $this->expectException(Exception::class);
      }
      
      public function returns_server_erro()
      {
          // Arrange, Act
          ...
          // Assert
          $response->assertStatus(500);
      }
      
    2. 在测试名称中赋予测试意义。当您不记得某事意味着要做什么而不是实际做什么时,这将极大地帮助您。

      public function it_should_not_have_a_message_if_the_input_is_wrong()
      {
           // database test
      }
      
      public function it_should_throw_an_exception_if_the_input_is_wrong()
      {
           // exception test
      }
      
      public function it_should_return_a_500_error_if_the_input_is_wrong()
      {
           // http code test
      }
      
      

    一个好的测试应该能够回答以下问题:

    如果我像 this 那样设置我的应用程序,然后我这样做 that,那么我的应用程序现在应该看起来像 this >

    这就是上面代码中 Arrange(组织我的应用程序)、Act(做某事)和 Assert(检查我的应用程序)的来源。

    您可能还需要查看其他几项内容,但这取决于您的需要。

    • 您似乎正在对此处的输入进行验证。如果您的输入错误,您可能应该抛出 400 或 422 错误
    • 您的异常中的 500 错误代码可能不会真正做任何事情,它不会与 500 HTTP 状态代码相关,除非您的错误处理中有这样做的东西。

    【讨论】:

    • 谢谢。但是..$this-&gt;expectException(Exception::class) 仍然无法使用/不使用。我想我做错了什么。但是,这个:$this-&gt;assertSame($response-&gt;exception-&gt;getMessage(), 'error'); 是工作。这是正确的决定吗?
    猜你喜欢
    • 2013-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-31
    • 2019-09-29
    • 1970-01-01
    • 2011-08-06
    • 1970-01-01
    相关资源
    最近更新 更多