覆盖对象属性以进行单元测试 [英] Override Object Property for unit testing purposes

查看:89
本文介绍了覆盖对象属性以进行单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Jest在Node.js应用程序上执行单元测试,该代码源是用TypeScript编写的,然后编译为JavaScript.

I am using Jest to perform unit tests on a Node.js app, where the code source is written in TypeScript and then compiled into JavaScript.

在我要测试的一个类中,导入了一个外部模块,并使用了该模块中的方法.为了只测试我的代码,我想模拟对此方法的调用.

In one of the classes that I wish to test, an external module is imported and a method from this module is used. I want to mock the calls to this method, in order to test only my code.

但是,当我运行测试时,出现以下错误:

However, when I run the test, I get the following error:

TypeError: Cannot redefine property: methodName

问题在于此方法具有以下对象属性:

The problem is that this method has the following Object Properties:

{ value: [Function],
  writable: false,
  enumerable: true,
  configurable: false }

configurable: false是一个大问题.在进行模拟调用以使其可写之前,我无法重新定义属性.

The configurable: false is what makes it a big problem. I cannot redefine the properties before my mock call to make it writable.

相关代码如下所示:

经过测试的课程

import externalType from 'external-module-name';

export class ClassName {
    public propertyName: externalType;

    public method(param: string): Promise<any> {
        return new Promise((resolve, reject) => {
            this.propertyName.externalMethod(param)
            .then((res) => {
                resolve(res);
            })
            .catch((err) => {
                reject(err);
            });
        });
    }
}

单元测试

import { ClassName } from 'path/to/class';

describe('class', () => {
    const class = new ClassName;

    it("Blahblah", (done) => {
        Object.defineProperty(class['propertyName'], 'externalMethod', {writable: true});
        const spy = jest.spyOn(class['propertyName'], 'externalMethod').mockReturnValue(Promise.resolve());
        class.method('string')
        .then((result) => {
            // Various expect()
            done();
        });
    });
});

到目前为止我尝试过的事情

  1. 我在测试中添加了以下行:

  1. I added the following line in my test:

Object.defineProperty(class['module'], 'methodName', {writable: true});

我的模拟调用定义如下:

I defined my mock call as following:

jest.spyOn(class['module'], 'methodName').mockReturnValue(Promise.resolve());

我的模拟调用定义如下:

I defined my mock call as following:

class.propertyName.externalMethod = jest.fn().mockImplementation((query) => { return Promise.resolve(); });

class.propertyName.externalMethod = jest.fn().mockImplementation((query) => { return Promise.resolve(); });

我尝试覆盖正在调用的属性,如下所示:

I tried to override the property that I'm calling, as following:

class.propertyName = <any> { externalMethod = (param: any) => { return Promise.resolve(); } }

class.propertyName = <any> { externalMethod = (param: any) => { return Promise.resolve(); } }

对于此错误,我得到错误TypeError: Cannot assign to read only property externalMethod of object class,这是有道理的,因为可读性设置为false.

For this one I get the error TypeError: Cannot assign to read only property externalMethod of object class, which makes sense since readable is set to false.

但是属性configurable似乎所有内容都被阻止.我肯定有可以做的事情,因为我可能不是唯一想在导入外部模块的类上执行单元测试的人,因为它是如此安全.

But everything seems blocked from the attribute configurable. I'm sure there is something that can be done because I am probably not the only one who wants to perform unit tests on a class that imports an external module, as secure as it is.

所以我的问题是:什么是模拟外部方法的干净且可行的方法?如果绝对不可能,什么是无需调用即可测试我的类的方法?那种外部方法?

So my question is: what would be a clean and working way of mocking the external method? And if it is strictly impossible, what would be a way of testing my class without calling that external method?

提前谢谢!

推荐答案

我发现这样做是

jest.mock('path/to/class');

我能够解决这个问题.

这篇关于覆盖对象属性以进行单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆