如何在另一个服务中从外部文件注入服务模拟

How to inject a mock of a service from an external file, in another service

我正在测试依赖于另一个服务 B 的服务 1。通常正确的做法是在注入 A 之前使用 $provide 对象。但是,我有两个限制条件:

问题是,到目前为止(我正在测试控制器),为了能够从我的测试中访问服务 B,我需要注入它。但是要在 $provide 中模拟它,我需要在我的测试中已经可以访问它,这会带来问题,因为 $provide 需要在任何 inject() 之前使用。这是我的测试:

describe('viewsListService', function() {
    var viewList,
        queryDeferred,
        mockViews,
        $scope;

    beforeEach(module('BoardMocks'));
    beforeEach(module('Board'));

    beforeEach(inject(function(mockViewsService) {
        var query = {};
        mockViewsService.init({}, query);
        queryDeferred = query.deferred;

        mockViews = mockViewsService.mock;
    }));

    beforeEach(function() {
        angular.mock.module('Board', function ($provide) {
            $provide.value('Views', mockViews);
        });
    });

    beforeEach(inject(function(viewsListService, $rootScope) {
        $scope = $rootScope.$new();
        viewList = viewsListService;

        // Initialisation of the viewsListService
        viewList.init();
        queryDeferred.resolve([1]);
        $scope.$digest();
    }));

    describe('getAllViews', function() {
        var allViews;

        beforeEach(function() {
            allViews = viewList.getAllViews();
        });

        it('should return all the views', function() {
            expect(allViews.length).toBe(1);
        });
    });
});

这给了我一个 Error: Injector already created, can not register a module!,指向 angular.mock.module 调用。

我把我的模拟服务移到另一个模块,想着也许它会解决问题,想知道注入器是否特定于某个模块,但它似乎不是(将 beforeEach(module('Board'));第一个 inject() 没有解决问题。

你有什么想法让它工作,同时将模拟保存在外部文件中(我可以不将其注册为 Angular 服务,但只是注册到一个普通对象,如果它可以解决这个)。

环顾四周后,我找到了 Valentyn Shybanov 的回答,解释了如何做到这一点。其实很简单。我会把它留在这里给其他迷失的灵魂。

Actually in AngularJS Dependency Injection uses the 'last wins' rule. So you can define your service in your test just after including your module and dependencies, and then when service A that you're testing will request service B using DI, AngularJS will give mocked version of service B.

所以如果你想模拟 "Views" 服务。您创建了一个包含 "Views" 服务的 "BoardMocks" 模块。如果在 "Board" 之后包含 "BoardMocks",则在测试期间将使用模拟的 "Views" 服务。

在此处查看原始答案: Injecting dependent services when unit testing AngularJS services