1

質問: Jasmine Unit Test ができるように pointFactory を偽造するにはどうすればよいですか。

次のディレクティブがあります。html がファクトリに送信され、いくつかのロジックに応答が使用されます。

CommonDirectives.directive('TextEnrichment',['PointFactory','appSettings', function (pointFactory,settings) {
    return {
        restrict: 'A',
        link : function (scope, element, attrs) {
         var text = element.html();
         pointFactory.getPoints(text).then(function(response){

 })}}}]);

これまでのところ、単体テストは次のようになっていますが、ファクトリを注入していないため機能しません。

beforeEach(module('app.common.directives'));

beforeEach(function () {
    fakeFactory = {
        getPoints: function () {
            deferred = q.defer();
            deferred.resolve({data:
                [{"Text":"Some text"}]
            });
            return deferred.promise;
        }
    };
getPointsSpy = spyOn(fakeFactory, 'getPoints')
        getPointsSpy.andCallThrough();

 });

beforeEach(inject(function(_$compile_, _$rootScope_,_$controller_){
        $compile = _$compile_;
        $rootScope = _$rootScope_;
    }));

it('Factory to have been Called', function () {
    var element = $compile('<div data-text-enrichment=""> Text </div>')($rootScope)
    expect(getPointsSpy.callCount).toBe('1');
});

アップデート

Felipe Skinner からのアドバイスに従って、次のようにテストを更新しました。

  beforeEach(function(){
       module(function($provide){
           $provide.factory('PointFactory',getPointsSpy)
       })
});

ただし、次のエラーが表示されます。

TypeError: 'undefined' は関数ではありません ('pointFactory.getPoints(text)' を評価しています)

4

1 に答える 1

1

$provide を使用して、コントローラーの依存関係を注入できます。たとえば、私の beforeEach は次のとおりです。

describe('MyCtrl', function() {
    var $controller,
        $scope,
        $httpBackend,
        windowMock,
        registerHtmlServiceMock,
        mixPanelServiceMock,
        toastMock;

    beforeEach(function() {
        windowMock =  { navigator: {} };
        registerHtmlServiceMock = {};
        mixPanelServiceMock = jasmine.createSpyObj('mixpanel', ['track']);
        toastMock = jasmine.createSpyObj('toast', ['error']);

        module('myModule');
        module(function($provide) {
            $provide.value('$window', windowMock);
            $provide.value('RegisterHtmlService', registerHtmlServiceMock);
            $provide.value('MixPanelService', mixPanelServiceMock);
            $provide.value('ToastService', toastMock);
        });

        inject(function(_$controller_, _$rootScope_, _$httpBackend_) {
            $scope = _$rootScope_.$new();
            $controller = _$controller_('CourseSelectionCtrl', { $scope: $scope });
            $httpBackend = _$httpBackend_;
        });
    });

    // my test cases

});

何らかの値を返す関数をモックしようとはしていません。これらの 2 つのモック (mixpanel-track と toast-error) は、"void" 関数用です。

アップデート:

次に、このタイプのインジェクションで以前の $provide を変更してみてください。

これから変更します:

module(function($provide) {
    $provide.value('$window', windowMock);
    $provide.value('RegisterHtmlService', registerHtmlServiceMock);
    $provide.value('MixPanelService', mixPanelServiceMock);
});

inject(function(_$controller_, _$rootScope_, _$httpBackend_) {
    $scope = _$rootScope_.$new();
    $controller = _$controller_('CourseSelectionCtrl', { $scope: $scope });
    $httpBackend = _$httpBackend_;
});

これに:

    beforeEach(inject(function(_$controller_, _$rootScope_, _$httpBackend_) {
        mixPanelService = mixPanelServiceMock;
        $scope = _$rootScope_.$new();
        $controller = _$controller_('MyCtrl', { $scope: $scope, MixPanelService: mixPanelService });
        $httpBackend = _$httpBackend_;
    }));

それを除いて、コードの残りの部分は同じである必要があります。これがうまくいくかどうか教えてください

于 2013-08-02T18:24:46.943 に答える