【问题标题】:Jasmine testing stateful serviceJasmine 测试有状态服务
【发布时间】:2019-05-08 16:24:18
【问题描述】:

我是 Jasmine 测试的新手,正在寻找一种“最佳实践”来对有状态的 AngularJS 服务进行单元测试。我能找到的大多数教程都侧重于对无状态服务运行原子调用的测试用例。

这很好地匹配了 Jasmine 语法

it("should do something", function(){ expect(target.doSomething()).toBe... })

但是,我发现没有明显的方法可以将此模式扩展到涉及对一个或多个服务函数的多次调用的测试用例。

让我们想象一下这样的服务:

angular.module("someModule").factory("someService", function(){
  return { 
    enqueue: function(item){
      // Add item to some queue
    }
  }
});

对于这样的服务,测试对enqueue() 的连续调用以正确的顺序处理项目是有意义的。这涉及编写一个多次调用enqueue() 并检查最终结果的测试用例(显然不能使用上述简单的服务来实现,但这不是重点……)

什么不起作用:

describe("Some service", function(){
  // Initialization omitted for simplicity
  it("should accept the first call", function() { 
    expect(someService.enqueue(one)).toBe... // whatever is correct 
  });
  it("should accept the second call", function() { 
    expect(someService.enqueue(two)).toBe... // whatever is correct 
  });
  it("should process items in the correct order", function() { 
    // whatever can be used to test this
  });
});

上面的代码(实际上不是定义一个而是三个测试用例)随机失败,因为三个测试用例被执行......就像随机一样。

this thread 中的一位发帖人建议将代码分成几个 describe 块将按照给定顺序执行这些代码,但这似乎又与一个 Jasmine 版本不同(根据其他发帖人相同的线程)。此外,以随机顺序执行套件和测试似乎是预期的方式。即使通过设置可以覆盖此行为,这也可能不是正确的方法。

因此,测试多调用场景的唯一正确方法似乎是使其成为一个测试用例,如下所示:

describe(("Some service", function(){
  // Initialization omitted for simplicity
  it("should work in my complex scenario", function(){
    expect(someService.enqueue(one)).toBe... // whatever is correct 
    expect(someService.enqueue(two)).toBe... // whatever is correct 
    expect(/* whatever is necessary to ensure the order is correct */);
  });
});

虽然从技术角度来看,这似乎是合乎逻辑的方式(毕竟,复杂的场景是一个测试用例而不是三个),Jasmine “描述 + 代码”模式在这个实现中似乎受到了干扰:

  • 无法将消息与测试用例中可能失败的每个“子步骤”相关联;
  • 对于单个“它”的描述不可避免地很冗长,就像上面的示例一样,要真正说明复杂场景的有用信息。

这让我想知道这是否是这种测试需求的唯一正确解决方案(或者是它?)。再次,我对“以正确的方式做事”特别感兴趣,而不是使用某种可以使它工作的黑客......在它不应该的地方。

【问题讨论】:

    标签: javascript angularjs unit-testing jasmine


    【解决方案1】:

    抱歉没有代码...不确定它是否需要,我认为您只需要调整您对测试的期望即可。

    对于测试的一般规则,您并不真正关心外部依赖项如何处理服务,您无法控制它。您想测试您认为预期结果将对您的服务产生什么影响。

    对于您的示例,您只需调用服务的依赖项并调用函数并测试调用 enqueue 函数的预期结果。如果它返回一个承诺,检查成功和错误。它调用 API 检查等等。

    如果您想了解外部依赖项如何使用您的服务,您将在这些依赖项测试中对其进行测试。

    例如,您有一个调用enqueue 的控制器。在测试中,您必须注入您的提供者(服务)。并处理期望。

    【讨论】:

      猜你喜欢
      • 2012-10-12
      • 2018-12-23
      • 2017-12-14
      • 2016-07-09
      • 2014-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-23
      相关资源
      最近更新 更多