Javascript 茉莉花间谍和如何使用间谍一般

Javascript 茉莉花间谍和如何使用间谍一般,javascript,unit-testing,jasmine,spyon,Javascript,Unit Testing,Jasmine,Spyon,我从JS单元测试开始,很难理解如何使用Jasmine spies创建有意义的测试 it('should take an array of shopping items', function() { spyOn(checkObj, 'getTotal'); checkObj.getTotal([1, 2, 3]); expect(checkObj.getTotal).toHaveBeenCalledWith(jasmine.any(Array)); }); 以上面我创建的测试摘录为例

我从JS单元测试开始,很难理解如何使用Jasmine spies创建有意义的测试

it('should take an array of shopping items', function() {
  spyOn(checkObj, 'getTotal');
  checkObj.getTotal([1, 2, 3]);
  expect(checkObj.getTotal).toHaveBeenCalledWith(jasmine.any(Array));
});
以上面我创建的测试摘录为例,我看不出这是一个多么有用的测试,因为我对getTotal的调用在规范中是硬编码的。但同时,我想确保传递的参数是一个数组,而不是其他类型……我确信硬编码是错误的


有人能给我提供一些关于我应该如何思考/处理这种类型的测试场景的指导吗。这在很大程度上取决于您自己如何定义单元测试的范围。如果您使用最小可能单位(即方法),那么让我们想象以下情况:

var x = function() { }
x.prototype.f1 = function() { 
        //do something 
        },
x.prototype.f2 = function(){
          // do something else
          this.f1();
        }
现在,在f2的单元测试中,您对f1内部的工作方式不感兴趣。所以,你在它上面做了一个间谍:

var a = new x();
a.f1 = jasmine.createSpy("spy-on-f1");
expect(a.f1).not.toHaveBeenCalled();
a.f2();
expect(a.f1).toHaveBeenCalled();
例如,对于angularjs应用程序,我经常用spies模拟整个服务,只是为了在测试中隔离算法

作为奖励,您实际上可以使用以下伪函数替换真实调用:

a.f1 = jasmine.createSpy("fake-spy").and.callFake(function(){
    // do something predictible or return global variable that can be set externaly
});

我认为你在这里看到的问题是错误的。问题是你想测试什么?您现在拥有的代码是相当无用的-您使用数组调用它,并在下面的一行检查它是否使用数组调用。这实际上是在测试你的测试。换句话说,这不是一件有用的事情去验证。你想在这里检查什么是更好的问题?如果您想检查
getTotal
是否只接受数组,那么您可能需要用其他东西调用它,并预期会出现某种错误。谢谢您的评论vlaz,您所说的很有意义,使用TohaveCalledWith测试参数感觉我做了错误的事情,最好是简单地测试方法的输出。我也会尝试一下你的想法……我只想检查数组是否作为参数传递,但不确定我是否试图过度测试