在单元测试用例中模拟 Angular $window

Posted

技术标签:

【中文标题】在单元测试用例中模拟 Angular $window【英文标题】:Mocking Angular $window in unit test cases 【发布时间】:2015-08-24 20:03:13 【问题描述】:

我一直在尝试对我用 Typescript 编写的 Angular 自定义服务进行单元测试。该服务读取在 Window 对象上定义的全局变量。我已经承诺,以便将来我可以进行 AJAX 调用来获取此信息。这是我的精简服务:-

export class ProxyDetectiveService 
    public static $inject = [
        $window,
        $q
    ];

    constructor(private $window:ng.IWindowService,
                private $q:ng.IQService) 
    

    public getProxyUserObject = ():ng.IPromise<any> => 
        this.log.debug('Proxy User Service called, to get proxy user details');

        var deferred = this.$q.defer();
        var proxyDetails = this.$window.portalObject;
        deferred.resolve(proxyDetails);

        return deferred.promise;
    ;


我的单元测试用例:-

describe('Proxy Detective Service - Unit Test Cases', () => 
    var proxyDetectiveService:any,
        $window:ng.IWindowService;

    beforeEach(() => 
        module('myApp');
    );

    beforeEach(inject(($injector:ng.auto.IInjectorService, _$window_) => 
        proxyDetectiveService = $injector.get('ProxyDetectiveService');
        _$window_ = 
            portalObject: 
                proxyUserDetails: 
                    firstName: 'testFN',
                    lastName: 'testLN'
                
            
        ;
    ));

    it('should have proxy object defined', function () 
        var promise = proxyDetectiveService.getProxyUserObject();
        promise.then(function (response) 
            expect(response).toBeDefined();
        ).catch(function (response) 
            expect(response).toBeUndefined();
        );
    );
);

这是我的问题:-

    我的测试用例已执行,但我在服务中没有看到模拟的窗口对象?

    我的 promise then 或 catch 子句永远不会被执行?

    有没有更好的方法可以实现我的服务?我的意图是返回一个承诺,将来我可能会使用 AJAX 调用。

【问题讨论】:

【参考方案1】:

您需要使用$provide 在单元测试中提供模拟值:

beforeEach(() => 
    module('myApp', ($provide) => 
      $provide.value('$window', myMockedWindowObject)
    );
);

您还需要调用 $rootScope.$apply() 以在单元测试中推进 Promise。

【讨论】:

以上是关于在单元测试用例中模拟 Angular $window的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在 IOS 的 XCTest 单元测试用例中模拟方法(带参数)调用

无法绑定到“(ngModel”,因为它不是角度单元测试用例中“输入”的已知属性

在 Laravel 测试用例中模拟一个 http 请求并解析路由参数

如何在单元测试中模拟缺乏网络连接

Python单元测试:在单元测试用例中转换旧测试

如何在量角器测试用例中模拟“Control + Space”?