【问题标题】:Globally mock object in angularjs for jasmine/karma testing在 angularjs 中全局模拟对象以进行 jasmine/karma 测试
【发布时间】:2014-05-17 04:21:40
【问题描述】:

我有一个对象,我正在模拟进行单元测试。基本上在我的测试文件中,我将其模拟如下:

var mockObject = {
    mockMethod1 : function() {return true},
    mockMethod2 : function() {return true}
};


beforeEach(module('myModule') , function ($provide) {
    $provide.value('realObject',mockObject);
});

我的理解是,当我在我的模块等中测试功能时......任何引用“realObject”的地方都将使用我的“mockObject”

我的问题是我制作了多个用于测试的 js 文件,我不想在每个文件中定义我的“mockObject”......我也不想在比我拥有的更多的地方维护它。

有没有办法将我的“mockObjact”移动到一个单独的文件中,该文件包含在 karma.conf.js 中,这将使“mockObject”可用于注入我的任何测试文件.....我在考虑你如何注入 $rootScope

【问题讨论】:

    标签: javascript angularjs unit-testing jasmine karma-runner


    【解决方案1】:

    如果它是在特定套件的上下文之外编写的,但仍由 Jasmine 执行,您可以创建一个全局 beforeEach 函数,例如创建一个自定义文件以由 Karma 加载并在那里编写 beforeEach 函数,而不将其包含在 describe 函数中。

    例子:

    var myGlobal;
    
    beforeEach(function() {
        // This will run before any it function.
        // Resetting a global state so the change in this function is testable
       myGlobal = 10
    });
    
    describe('first suite', function(){
      it('is a test', function(){
          expect(myGlobal).toBe(10);
          // Set the value to show that beforeEach is executed for each it function
          myGlobal = 20;
          expect(myGlobal).toBe(20);
      });
    
      it('is another test', function(){
          expect(myGlobal).toBe(10);
          myGlobal = 30;
          expect(myGlobal).toBe(30);
      });
    });
    
    describe('second suite', function(){
      it('is a test', function(){
          expect(myGlobal).toBe(10);
      });
    });
    

    见小提琴here

    【讨论】:

    • 是的,我目前将它作为全局写入测试文件中......问题是我想在多个测试文件中使用这个模拟对象,并希望维护这个对象的尽可能少的副本可能。
    • 什么是全局?模拟对象?您是否在多个文件中提供服务价值?因为这就是答案 - 在单个文件中为所有测试提供模拟值
    • 我想我不清楚究竟如何使用 $provide 来获取新创建的服务中将返回 mockObject 的函数。我之前所做的只是在测试中创建模拟对象,然后使用提供。
    • 这就是你应该做的。问题是您只能在单个文件中的单个 beforeEach 函数中执行一次,如果 beforeEach 不是套件的一部分,它将在任何测试之前运行
    • 这仍然缺少一块......在我的测试文件中,我创建了一个模拟对象......我使用提供来获取要在我的测试中使用的模拟对象,而不是 "realObject" 。 ...所有这些都很好...缺少的部分是我的模拟对象“是”的定义现在驻留在服务中,因此我可以在多个测试文件中使用它并且只在一个地方管理它。我究竟是如何按照 var mockObject = myService.getMockObject()
    【解决方案2】:

    您可以构建一个包含您的模拟的服务,并将该服务注入每个测试文件中。

    beforeEach(inject(function($rootScope, $controller, yourMockSvc) {
        appScope = $rootScope.$new();
        appCtrl = $controller('AppController', {
            $scope: appScope,
            yourSvc: yourMockSvc
        });
    }));
    

    【讨论】:

    • 我听说你打算把它变成一项服务。但我设想它的方式是我希望能够在我的测试顶部设置一些东西,比如: var myMockObject = myService.getObject();然后在其余的测试中使用该模拟对象
    【解决方案3】:

    只需在另一个文件中定义您的模拟对象并将其导出。您应该可以在任何文件中使用它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-29
      • 1970-01-01
      • 1970-01-01
      • 2013-12-20
      • 1970-01-01
      • 2016-10-06
      • 2014-05-04
      • 1970-01-01
      相关资源
      最近更新 更多