2015-04-12 59 views
0

用茉莉花可以用spyOn方法,但我不清楚它什么时候会有用。我的理解是,单元测试不应该关注实现细节,并且测试方法是否是实现细节。什么时候在单元测试期间监视有用的方法?

我可能会想到的一个地方是scope.$broadcast(Angular)等间谍,但是这又会是实现细节,并且不确定单元测试是否应该对代码的工作方式产生影响,只要它能给出预期的结果即可。

显然有很好的理由使用spyOn所以什么是使用它的好地方?

+0

“测试不应该关注实现细节和测试,如果方法被调用将是实现细节”---它取决于。当你实现一个缓存层时,你需要确保底层的存储库只被调用一次,之后从缓存中提供内容。 – zerkms

回答

0

你的描述是在测试作为一个模拟更俗称,虽然更明确允许2次的运算spyOn:

  1. 创建通过createSpy的方法的新的实现(这是经典模拟)

  2. 仪器通过spyOn现有的方法(这可以让你看到,如果方法被调用以怎样的指定参数时,返回值等)

嘲笑单元测试中最常用的技术。当你测试一个代码单元时,你会经常发现其他代码单元存在依赖关系,而这些依赖关系有它们自己的依赖关系等。如果你试图测试所有的东西,你最终会得到一个模块/ UI测试,它们很昂贵且难以维护(它们仍然很有价值,但你希望尽可能少的那些)

这是模拟进入的地方。想象一下你的设备调用REST服务来获取某些数据。您不希望在单元测试中依赖服务。所以你嘲笑调用服务的方法,并提供你自己的实现,只是返回一些数据。想要检查你的单元是否处理REST错误?让你的模拟返回一个错误。等等

有时候知道你的代码是否实际调用另一个代码单元有时会很有用 - 假设你想确保你的代码正确地调用一个日志模块。只是模拟(spyOn)记录模块并断言它被称为具有正确参数的X次。

0

你可以间谍功能,然后你就可以断言关于它的几件事 。你可以检查它是否被调用,它有什么参数,如果它返回了一些东西,甚至被调用了多少次! 间谍在编写测试时非常有用,所以我将解释如何在这里使用其中最常见的方法。

 // This is our SUT (Subject under test) 
     function Post(rest) { 
      this.rest = rest; 
     rest.init(); 
     } 

我们在这里有我们的SUT,它是一个Post构造函数。它使用RestService来获取其内容。我们的帖子会将所有剩下的工作委托给RestService ,当我们创建一个新的Post对象时,它将被初始化。让我们开始逐步测试 它一步一步:

`describe('Posts', function() { 
     var rest, post; 
     beforeEach(function() { 
     rest = new RestService(); 
     post = new Post(rest); 
     }); 
    });` 

这里没有新东西。由于我们将在每次测试中都需要两个实例,因此我们将初始化设置为beforeEach,因此每隔 时间就会有一个新实例。 创建后,我们初始化RestService。我们要测试的是,我们如何 能做到这一点?:

`it('will initialize the rest service upon creation', function() { 
     spyOn(rest, 'init'); 
     post = new Post(rest); 
     expect(rest.init).toHaveBeenCalled(); 
    });` 

我们要确保当我们创建了一个新的 Post对象上休息的init被调用。为此我们使用jasmine spyOn函数。第一个参数是 我们想要放置间谍的对象,第二个参数是一个字符串,其中 代表间谍的功能。在这种情况下,我们希望窥探间谍对象上的功能init 。然后我们只需要创建一个新的Post对象,该对象将调用 init函数。最后一部分是声明rest.init已被调用 。容易吗?这里重要的是,当你窥探一个功能时,真正的功能是永远不会被调用的。所以这里rest.init实际上并不是 运行。

相关问题