【问题标题】:How to test multiple PHP TypeErrors in one test?如何在一次测试中测试多个 PHP TypeErrors?
【发布时间】:2021-09-25 10:18:18
【问题描述】:

我有以下方法:

MyClass {
   public function __construct(array $data, ?SomeObject $object): void
}

我有以下测试:

public function testWrongDataTypeThrowsErrorException(): void
{
    $this->expectException(TypeError::class);

    //works as expected
    new MyClass(null, new SomeObject);
    
    //this is never called
    new MyClass('string', new SomeObject);
}

发生的情况是它只使用 null 参数运行 1 个测试/断言。第二次尝试使用字符串创建 MyClass 时,它永远不会到达那里。这是为什么呢?

如果代码抛出常规异常,同样的逻辑会起作用。

我可以写 2 个单独的方法来代替,但这很不方便。

或者测试这个是愚蠢的吗?我的想法是我想测试该方法是否接受数组并且只接受数组。因此,如果有人将其从方法中删除,则测试将失败。

【问题讨论】:

    标签: php unit-testing testing phpunit


    【解决方案1】:

    仅将expectExeception...exepectError... 直接放在您要为其声明的操作之前。

    如果您需要多个,请编写多个测试方法 - 分别针对每个异常和错误。


    上面的建议是它如何与 Phpunit 开箱即用并通常保持您的测试干净。

    然而,也可以选择在这里使用 PHP 并像下面这样处理它:

    try {
        new MyClass(null, new SomeObject);
        $this->fail('an expected exception was not thrown');
    } catch (TypeError $e) {
        $this->addToAssertionCount(1);
    }
    

    那么测试方法不会被中断,你可以继续(你必须移除之前的 TypeError 预期,因为 Phpunit 将不再检测它)。

    如果你觉得这比分开测试更方便,那就去吧。

    你甚至可以添加一个辅助函数并传入一个闭包,这样你就可以包装它。通常最好坚持使用干净的测试恕我直言,如果你真的必须测试的话。

    根据您在问题中所写的内容,我想说自从 PHP 5 中的 array 类型提示回到 PHP 5 以来,问题已在 PHP 中得到解决。???我不需要对此进行测试(或者您还需要为您的测试编写测试,因为测试也可以更改)。

    如果有人更改了方法签名,他们应该有正当理由。如果他们犯了错误,他们可能没有用测试来覆盖他们的重构,所以问题不在于单元的代码,也不是用单元测试来测试。


    请记住,测试应该只有一个失败的原因。因此,在编写(单元)测试时,最好以此为目标。

    【讨论】:

    • 嗯,好吧,这不是我所希望的 :) 我知道如果某些开发人员后来决定删除方法签名是他的错……但这就是我想测试这个的原因。无论如何,我决定放弃这些测试。否则我将不得不编写 99% 相似的 20 个测试。
    • @Honza:如果您想对此进行测试,请不要为它编写测试。使用执行此操作的检查器,例如Roave Backward Compatibility Check 可以跟踪跨版本的接口更改并报告它们。它也不能撒谎,例如编辑测试以使新事物在破坏时“工作”。
    猜你喜欢
    • 2016-04-05
    • 2017-05-26
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-11
    • 1970-01-01
    • 2020-11-12
    相关资源
    最近更新 更多