具有外部依赖关系的单元测试ES6类

时间:2018-11-20 17:09:26

标签: javascript unit-testing mocking mocha

我正在尝试为我的公司设置单元测试样板。我们的前端项目是使用ES6类构建的,并且依赖于我们的核心产品。前端代码在整个构建过程中被包装在其他整个代码块中,这些代码块基本上是一个闭包并捕获了依赖性。因此,我们无需手动导入即可使用它。

比方说,该依赖项称为productScope,它是一个对象,它具有一些DOM模型,内部API和参数以及每个项目所需的许多其他功能。目前,摩卡咖啡会抛出ReferenceError: productScope is not defined.我该如何模拟该对象?还是应该只使用实际对象?

示例:

class someClass {
    constructor() {
        const id = productScope.items[0].id
        const item = productScope.domModel.querySelector('.some-div')

        item.classList.add(`added-${id}`)
    }
}

这被包裹在如下的核心代码中:

(function(productScope) {
    // front end code goes here
}(productScope)

测试文件:

import someClass from '../../js/someClass'

describe('someClass', function() {
    const someClass = new someClass()
    it('should be a class', function() {
        console.log(someClass)
    });
});

3 个答案:

答案 0 :(得分:0)

好像productScope是全局变量。

类似的东西应该对您有用。

import someClass from '../../js/someClass';

describe('someClass', function() {
    let someClass;

    beforeEach(() => {
        global.productScope = {
          // you mock definition
          someClass = new someClass();
        };
    });

    it('should be a class', function() {
        console.log(someClass)
    });
});

答案 1 :(得分:0)

您可以尝试这样的事情

describe('#someClass', () => {
    let someClass;

    beforeEach(() => {
        global.productScope = {
            // mocking productScope object
        };
    });

    it('should be a class', () => {
        someClass = new SomeClass;
        console.log(someClass);
    });

    afterEach(() => {
        delete global.productScope;
    });
});

或者如果您想为每个测试用例提供更具体的模拟逻辑

describe('#someClass', () => {
    let someClass;

    it('should be a class', () => {
        global.productScope = {
            // mocking productScope object
        };

        // Test logic start

        someClass = new SomeClass;
        console.log(someClass);

        // Test logic end

        delete global.productScope;
    });
});

答案 2 :(得分:0)

我也有其他答案,因为管理global变量似乎是最简单,最直接的解决方案。

但是,您可以使用toString获取类的字符串表示形式,并使用eval将其绑定到闭包的范围:

class someClass {
   constructor() {
     this.id = scopedId
   }
}

// pass class as an argument
function scopeFactory(classDef) {

   // define scoped data
   let scopedId = 2;

   // eval is used to bind class to the local closure
   // so `scopedId` will be in charge
   return eval("(" + classDef + ")");
}

const scopedSomeClass = scopeFactory(someClass);

console.log(new scopedSomeClass)

请注意,eval(someCLass.toString()) doesn't work without parentheses

您可以将其作为辅助功能添加到您的项目中。