2016-01-09 104 views
1

這是我test_sp.js文件:茉莉花控制器和模擬服務測試

describe('Controller: MainCtrl', function() { 
    var ctrl, mockBaseService; 

    beforeEach(function() { 

     mockBaseService = { 
      cerrorMessages: 'whatever', 
      sp: "[{'spName': 'Test'}]", 
      // Calls back if errors. 
      add: jasmine.createSpyObj('BaseService.add', ['sp']), 
      logout: jasmine.createSpy('BaseService.logout'), 
      // Calls back if errors. 
      fetch: jasmine.createSpyObj('BaseService.fetch', ['selfsp']) 
     }; 

     mockBaseService.add.sp.and.callFake(function(something, cb) { 
      cb(); // execute the callback immediately 
     }); 

     mockBaseService.fetch.selfsp.and.callFake(function(something, cb) { 
      cb(); // execute the callback immediately 
     }); 

     module('SpPageApp'); 

     // Let ctrl = MainCtrl and override BaseService in MainCtrl to be 
     // the mockBaseService above. 
     inject(function($controller) { 
      ctrl = $controller('MainCtrl', { 
       BaseService: mockBaseService 
      }); 
     }); 
    }); 

    it('should have an add function', function() { 
     expect(ctrl.add).toBeDefined(); 
    }); 
}); 

這是我的人緣配置文件的file陣列:

files: [ 
    '../angular.js', 
    'node_modules/angular-mocks/angular-mocks.js', 
    '../w.js', 
    '../sp.js', 
    '../s.js', 
    '../base.js', 
    'tests/test_sp.js', 
], 

最後,這是我sp.js它具有SpPageApp模塊:

angular.module("SpPageApp", ["BaseApp"]) 
    .controller("MainCtrl", ["$http", "$window", "BaseService", function($http, $window, BaseService) { 

     var self = this; 

     BaseService.fetch.selfsp(function() { 
      self.sp = BaseService.sp; 
      self.cerrorMessages = BaseService.cerrorMessages; 
     }); 

     self.add = function() { 
      BaseService.add.sp(self.sp, function() { 
       self.cerrorMessages = BaseService.cerrorMessages; 
      }); 
     }; 

     self.logoutUser = function() { 
      BaseService.logout(); 
     }; 

    }]); 

的我做karma start測試代碼,我得到一個錯誤說這個:

Chromium 47.0.2526 (Ubuntu 0.0.0) Controller: MainsCtrl should have an add function FAILED 
    TypeError: Cannot read property 'and' of undefined 
     at Object.<anonymous> (/home/a/Documents/CMS/CMSApp/static/js/karma/tests/test_sp.js:20:45) 
    TypeError: Cannot read property 'add' of undefined 
     at Object.<anonymous> (/home/a/Documents/CMS/CMSApp/static/js/karma/tests/test_sp.js:36:20) 
Chromium 47.0.2526 (Ubuntu 0.0.0): Executed 1 of 1 (1 FAILED) (0 secs/0.006 secChromium 47.0.2526 (Ubuntu 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.034 secs/0.006 secs) 

錯誤說,它無法讀取屬性的定義add,並指出這條線:

expect(ctrl.add).toBeDefined(); 

,它無法讀取屬性未定義and,並指出這條線:

mockBaseService.fetch.selfsp.and.callFake(function(something, cb) { 

爲什麼茉莉說這兩個ctrlmockBaseService.fetch.selfsp在代碼中定義時未定義?

編輯:對於它的價值,w.jssp.jss.js(其業力加載)的所有已控制器稱爲MainCtrl但每個控制器是在它自己的文件和AngularJS模塊(在test_sp.js,我只加載SpPageApp模塊) 。

+0

當你已經嘲笑服務的時候,你爲什麼會稱假冒?只需撥打嘲笑的服務。 –

+0

@DavidL菲爾發佈在這裏的答案:http://stackoverflow.com/questions/34623322/flushing-successful-mock-post-request-using-jasmine-does-not-execute-the-angular在嘲笑時調用一個假的該服務,所以我決定也使用它(我是新來的茉莉花,所以我覺得菲爾做的是最佳實踐)。我相信這是因爲'ctrl.add()'將一個函數傳遞給'BaseService.add.sp',它應該被回調。 – user2719875

+0

他的答案的替代方案將如下所示:mockBaseService = { cerrorMessages:'whatever', add:function(){//無論添加函數應該做什麼} }; 在這種情況下,不是通過使用間諜對象來創建額外開銷,而是簡單地覆蓋該服務並將重寫的模擬服務注入到控制器中,因爲所有您關心的測試都是控制器而不是服務。 –

回答

2

正如我的評論中提到的,您可以直接嘲笑服務並避免使用間諜。另外,你可以告訴$注入器使用你的模擬服務而不是真正的實現,允許你在解析服務時直接注入模擬,這取代了你的正常實現。

假設你BaseService的SpPageApp模塊中存在:

mockBaseService = { 
    cerrorMessages: 'whatever', 
    sp: "[{'spName': 'Test'}]", 
    add: function (something, cb) { cb() }, 
    ... 
}; 

module('BaseApp', function($provide) { 
    $provide.value('BaseService', mockBaseService); 
}); 

module('SpPageApp'); 

inject(function($controller) { 
    ctrl = $controller('MainCtrl', { 
    }); 
}); 

爲了測試它,因爲在評論中提到的,你仍然想使用間諜來確保它成功調用。

it('should have an add function', function() { 
    spyOn(mockBaseService, 'add');   
    ctrl.add(); 
    expect(mockBaseService.add).toHaveBeenCalled(); 
}); 
+0

但mockBaseService需要'mockBaseService.add.sp()'函數(請參閱我的原始文章)。在你提供的答案中,'mockBaseService.add.sp()'不存在,對吧?另外,我想創建另一個測試,測試'ctrl.add()'通過調用'mockBaseService.add.sp()'(即'expect(mockBaseService.add.sp).toHaveBeenCalledWith (ctrl.post,jasmine.any(Function));'..是否可以查看函數是否被調用而不使用間諜? – user2719875

+0

最後,BaseService模塊中存在'BaseService'。 'BaseApp'模塊提供給'SpPageApp'如下:'angular.module(「SpPageApp」,[「BaseApp」])''base.js'被加載到karma配置文件中,像這樣:'files:['../base.js',],' – user2719875

+1

你可以修改你的模擬服務簽名來調用你想調用的任何東西,因此你可以定義add和add.sp。我已經更新了我的答案來匹配你的模塊,另外,如果你願意,你仍然可以監視你的模擬服務。一個模擬服務。 –