哪种方法最好单元测试组合代码?

时间:2016-03-31 19:04:31

标签: angularjs unit-testing

说我有以下AngularJs服务:

angular.module("foo")
    .service("fooService", function(){
        var svc = this;

        svc.get = function(id){...};
        svc.build = function(id){...};
        svc.save = function(thing){...}; //posts, then returns the saved thing
        svc.getOrCreate = function(id){
            return svc.get(id).then(function(thing){
                return thing || svc.build(id).then(function(builtThing){
                    return svc.save(builtThing);
                });
            });
        }
    });

我可以通过确保使用正确的数据确保找到正确的API端点来对get方法进行单元测试。

我可以测试build方法,确保它从正确的端点/服务中提取数据并构建它应该的内容。

我可以通过确保到达正确的API端点来测试save方法。

我应该怎么做才能测试getOrCreate方法?我对此有两种不同的看法:

  1. 隐藏getbuildsave方法,并在适当的时候验证它们,并使用适当的参数
  2. 存根getbuild中调用的API端点,然后验证save中的端点是否使用正确的参数调用
  3. 第一种方法基本上是说,"我知道这三种方法都有效,因为它们是经过独立测试的。我并不关心他们的实际工作方式,但我关心的是他们会在这种方法中被调用。"

    第二种方法是说,"我不关心这种方法在内部的作用,只是在达到正确的API端点"

    这些方法中哪一种更正确?#34;?我觉得第一种方法不那么脆弱,因为它独立于getbuildsave方法的实现方式,但它并不完全正确它正在测试实现而不是行为。但是,选项2要求我在多个测试区域中验证这些其他方法的行为,这似乎更脆弱,而脆弱的测试使人们讨厌编程。

    这是一个常见的权衡,我发现自己经常面对测试...任何人都有关于如何处理它的建议?

2 个答案:

答案 0 :(得分:1)

我已经看到它既有两种方式,也没有强烈的偏好。但就个人而言,我会考虑选项1,你不会在其他地方模拟其他功能进行集成测试,因为他们会调用多个公开可见的功能,因此更喜欢选项2。

答案 1 :(得分:1)

这将归结为意见问题。

如果您是单元测试,那么您的测试应该适用于非常具体的功能。

如果你开始追逐承诺,并且你有承诺链接,它会在哪里停止?

最重要的是,随着您的单元测试范围变得越来越大,它依赖的东西越来越多(服务,API等......),以及它可以制造的更多方式可能与之无关"单元&#34 ;.你想要确保有用的东西。

问题:如果你有一个可靠的控制器,可以很好地使用你的模板,并且有一个单元测试可以确保你的控制器坚如磐石。如果从Web服务http API调用的响应中解析出来的两个分离的承诺会破坏您的控制器测试吗?

另一方面,与通过模拟服务测试API客户端端点的方式相同,您可以使用Angular的$httpBackend服务等方式使用自己的测试来测试服务。