Karma 测试 lodash Factory

Karma testing lodash Factory

我已经在我的 angular 应用程序中为 lodash 库创建了一个工厂,如下所示:

angular.module('lodash',[]).service('_', function(){
    var _ = window._;
    // i am delete the _ property on the window
    // so that i m enforced to dependency inject
    // lodash each time i want to use it
    // instead of using the global lodash library
    delete window._;
    return _;
});

现在我想测试我的模块服务,我正在使用以下测试

describe('lodash', function() {
    // load the utilities module
    beforeEach(module('lodash'));

    describe('_', function() {
        it('should be defined', inject(function(_) {
            expect(_).not.toBe(null);
        }));
        it('should have toArray() defined', inject(function(_) {
            expect(_.toArray).toBeDefined();
        }));
    });
});

第二次测试没有成功。实现该功能的唯一方法是从我的服务实现中删除以下行。

delete window._;

我的问题来了:因为删除运算符只从 window 对象中删除 属性 而不是原始引用为什么删除 window._ 会破坏测试并且 _ 对象来了在测试中为空?

我记得有过类似的问题。不确定问题是否完全相同,但我解决了它,将 lodash 的属性复制到一个新对象中,然后我从工厂返回了它:

function lodash($window) {
    var lodashLib = $window._;
    var _ = {};

    delete( $window._ );

    // Instead of using directly what I got from the window object, I copy its properties
    // I cannot explain why this works better, but it solved the problem for me
    angular.extend(_, lodashLib);

    return _;
}

其次,我认为你应该小心测试 not.toBe(null)toBeDefined() 可能更好(有很多非常精确的方法可以用 Jasmine 进行测试)。最后,对于你的第二个测试,我认为正确的测试应该是 expect(typeof _.toArray).toBe('function');,它比仅仅被定义更具体一些:)

我希望我回答了你的问题,即使我对单元测试的了解总体上很乏味。

每次测试后你只需要return返回$window._
此代码应该可以正常工作:

describe('lodash', function() {
    var factory;

    // load the utilities module
    beforeEach(module('lodash'));

    beforeEach(inject(function (___) {
        factory = ___;
    }));

    afterEach(inject(function (_$window_) {
        _$window_._= factory;
    }));

    describe('_', function() {
        it('should be defined', function() {
            expect(factory).toBeDefined();
        });

        it('should have toArray() defined', function () {
            expect(factory.toArray).toBeDefined();
        });

        it('default keys method ->', function () {
            expect(factory.keys({"key1": "value1", "key2": "value2", "key3": "value3"})).toEqual(["key1","key2","key3"]);
        });
    });
});