【问题标题】:Should I Unit Test For a Call to $.ajax or that an XHR has been sent?我应该对 $.ajax 的调用或已发送 XHR 进行单元测试吗?
【发布时间】:2014-02-27 18:43:53
【问题描述】:

假设我有以下方法:

function sendUserDataToServer(userData) {
    // Do some configuration stuff
    $.ajax('SomeEndpoint', userData);
}

在为这个函数编写单元测试时,我可以采用以下两种方式之一:

  1. 围绕$.ajax 创建一个间谍并检查它是否使用预期的参数调用。不会发送实际的 XHR 请求。
  2. 使用 SinonJs 等库拦截 ajax 请求并检查 XHR 对象以确保其配置正确。

为什么我会选择选项 1:它将 $.ajax 的功能与我的代码分开。如果$.ajax 因 jQuery 中的错误而中断,它不会在我的单元测试结果中产生假阴性。

为什么我可能会选择选项 2:如果我决定使用除 jQuery 之外的另一个库来发送 XHR,我不必更改我的单元测试来检查不同的方法。但是,如果该库中存在错误,我的单元测试将失败,我不一定会立即知道它是库而不是我的实际代码。

哪种方法是正确的?

【问题讨论】:

    标签: javascript unit-testing


    【解决方案1】:

    您的第一个选项是正确的。单元测试的目的是双重的

    • 验证你的代码合约
    • 验证它是否与它使用的其他东西进行通信。

    您的问题是关于与$.ajax 的交互,因此此测试的目的是确认它可以与合作者正确对话。

    如果您选择选项 1,这正是您正在做的事情。如果您使用选项 2,则您正在测试第三方库,而不是您正在正确执行通信协议。

    不过,您应该同时进行这两项测试。第二个测试可能足够快,可以与您的单元测试一起使用,即使有些人可能将其称为集成测试。该测试告诉您正确地使用了该库来创建您想要创建的对象。两者都可以让您区分代码中的错误和库中的错误,如果库错误导致系统中的其他内容失败,这将派上用场。

    【讨论】:

      【解决方案2】:

      我的意见:选项 1 在单元测试中更正确。

      单元测试应该只测试代码单元。在您的情况下,这将是您控制下的 JavaScript(例如,函数内的逻辑、类或命名空间内,具体取决于函数的上下文)。

      您的单元测试应该模拟 jQuery 调用并相信它可以正常工作。进行真正的 AJAX 调用很好,但这些将是集成测试的一部分。

      请参阅this answer,了解什么是单元测试,什么不是单元测试。

      顺便说一句,第三种方法是通过自定义代理类进行 AJAX 调用,该代理类可以在测试中进行模拟,但也允许您切换使用的库。

      【讨论】:

        【解决方案3】:

        我会使用选项 1,但选择使测试最容易理解的选项。

        您在代码中依赖于 jQuery,因此您不必担心它实际上会像您指出的那样工作。我发现当您指定参数和响应并让您的代码处理它时,它会使测试更清晰。您还可以轻松指定应使用哪个回调(successerror)。

        至于从 jQuery 更改库。如果您更改代码,您的测试应该会失败。你可以争辩说你的行为现在不同了。是的,您正在进行 Ajax 调用,但具有不同的依赖关系。并且您的测试应该更新以反映这种变化。

        这两种方法都是正确的。如果您正在创建自己的包装器来发送 Ajax 调用,那么拦截 XHR 请求或手动创建请求并自己发送它可能是有意义的。选择使您的测试最容易理解和维护的选项。

        【讨论】:

          【解决方案4】:

          最重要的是测试你自己的代码。将业务逻辑与 IO 代码和您的业务逻辑分开。之后,您应该拥有没有任何逻辑来执行实际 IO 的方法(与您的示例完全相同)。现在:你应该测试那个方法吗?这取决于。测试是为了让你感觉更安全。

          • 如果您真的担心 jQuery 可能会失败,并且您无法承受这种不太可能发生的情况而不是对其进行测试。但不是使用一些模拟库,而是进行完整的端到端集成测试
          • 如果您不确定自己是否正确使用了 jQuery,请进行“学习测试”。将参数传递给它并检查它产生什么样的请求。在这种情况下,模拟测试就足够了
          • 如果您需要前端和后端之间的合同文档,那么您可以选择测试后端是否符合合同、前端或两者都符合
          • 但是,如果以上都不适用于您,那么测试外部完善的框架不是浪费时间吗? jquery 家伙肯定已经测试过了。您仍然可能需要某种集成测试(自动或手动)来检查您的前端是否与后端正确交互。这些测试将覆盖网络层

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-03-25
            相关资源
            最近更新 更多