2013-05-15 101 views
70

當單元測試一個Angular工廠(Karma + Jasmine)時,如何將stub依賴關係注入被測試工廠?單元測試有依賴關係的AngularJS工廠

這裏是我廠:

mod = angular.module('myFactoryMod', []); 

mod.factory('myFactory', [ 
    '$log', 'oneOfMyOtherServices', function($log, svc) { 
    return makeSomethingThatDoesSomethingWithTheseDependencies($log, svc); 
    } 
]); 

oneOfMyOtherServices實例我廠的時候是必要的。

這裏是我的測試:

it('can get an instance of my factory', function() { 
    var oneOfMyOtherServicesStub; 

    angular.mock.module('myFactoryMod'); 

    oneOfMyOtherServicesStub = { 
    someVariable: 1 
    }; 

    //****How do I get my stub in my target? **** 

    angular.mock.inject(['myFactory', function(target) { 

     expect(target).toBeDefined(); 

    } 
    ]); 
}) 

注:我知道$controller允許這個控制器,但我沒有看到工廠的等價物。

回答

85

有來完成這樣的事情,我知道的方法有兩種:

  1. 使用$provide和匿名模塊注入模擬。
  2. 注入您想要模擬的服務並使用茉莉花的間諜能力來提供模擬值。

第二個選項只有在您確切知道被測代碼將在注入的服務上調用哪些方法時纔有效,並且您可以輕鬆地將它們嘲笑出來。由於您似乎在訪問服務上的數據屬性(而不是方法),因此追求第一種選擇可能是最好的。

使用$provide將大致是這樣的:

describe('myFactory', function() { 
    // Load your module. 
    beforeEach(module('myFactoryMod')); 

    // Setup the mock service in an anonymous module. 
    beforeEach(module(function ($provide) { 
    $provide.value('oneOfMyOtherServicesStub', { 
     someVariable: 1 
    }); 
    })); 

    it('can get an instance of my factory', inject(function(myFactory) { 
    expect(myFactory).toBeDefined(); 
    })); 
}); 
+0

是的,我認爲選擇1是要走的路。謝謝! –

+6

我想將myFactory注入到所有測試中。它可以在beforeEach中完成嗎?我試過,但它沒有工作... –

+10

感謝您的回答+1。爲了完整性,還可以爲選項#2添加代碼示例。 – klode

8

通過@bentsai的評論實際上是測試服務很有幫助;爲了完整性,我添加了一個例子。

這是一個測試jasmine,它大約做你正在尋找什麼。注意:這要求您包含angular-mocks(這是提供的功能,如moduleinject)。

describe('app: myApp', function() { 
    beforeEach(module('myApp')); 
    var $controller; 
    beforeEach(inject(function(_$controller_) { 
    $controller = _$controller_; 
    })); 
    // Factory of interest is called MyFactory 
    describe('factory: MyFactory', function() { 
    var factory = null; 
    beforeEach(inject(function(MyFactory) { 
     factory = MyFactory; 
    })) 
    it('Should define methods', function() { 
     expect(factory.beAwesome).toBeDefined() 
     expect(factory.beAwesome).toEqual(jasmine.any(Function)) 
    }); 
    }); 
}); 

這是模塊和相關工廠的定義可能是什麼樣子存根:

var app = angular.module('myApp', []); 
app.factory('MyFactory', function() { 
    var factory = {}; 
    factory.beAwesome = function() { 
    return 'Awesome!'; 
    } 
    return factory; 
}); 

在這種情況下,很顯然使用的inject()讓你在依賴拉,就像你會期望在你正常的角度應用中 - 因此你可以建立需求來支持測試依賴它們的東西。

+2

您錯過了在測試中向MyFactory注入存根依賴的部分 – skolsuper

+0

第二個依賴關係在哪裏? – Choco

相關問題