React Native TypeError:_API.default不是具有Jest测试的构造函数

busg9geu  于 2022-11-17  发布在  React
关注(0)|答案(7)|浏览(385)

我有一个API类,我尝试在React应用中使用它。

// API file

class API {
...
}

export default API;

// Other file
import API from "utils/API";

const api = new API();

我得到的错误:

TypeError: _API.default is not a constructor

但是......我的默认设置好像已经设置好了?
我的Jest设置如下:

"jest": {
    "setupFiles": [
      "./jestSetupFile.js"
    ],
    "testEnvironment": "jsdom",
    "preset": "jest-expo",
    "transformIgnorePatterns": [
      "node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|react-native-svg|react-router-native/.*|@invertase/react-native-apple-authentication/.*)"
    ]
  },

强烈猜测这是由于我的babel、webpack或package.json的配置。
是什么原因导致的?
注意,我想澄清一下,这在我的主应用程序中不会发生,在Jest测试中发生
如果将其更改为命名的导出/导入,则会得到以下结果:

TypeError: _API.API is not a constructor

极度混乱的行为。

nzkunb0c

nzkunb0c1#

正如其他人所提到的,看到一个最小的可重复示例将是有帮助的。
然而,还有一个可能的原因。您是否在测试文件中模拟了API类?如果一个类被错误地模拟为“对象”而不是函数,有时会发生此问题。对象不能用“new”操作符示例化。
例如,假设我们有一个类文件utils/API,如下所示:

class API {
  someMethod() {
    // Does stuff
  }
}

export default API;

以下是模拟此类的“不正确”方式,如果在创建模拟后示例化该类,则会引发TypeError... is not a constructor错误。

import API from 'utils/API';

jest.mock('utils/API', () => {
  // Returns an object
  return {
    someMethod: () => {}
  };
})

// This will throw the error
const api = new API();

以下代码将该类模拟为函数,并接受new运算符,而且不会引发错误。

import API from 'utils/API';

jest.mock('utils/API', () => {
  // Returns a function
  return jest.fn().mockImplementation(() => ({
    someMethod: () => {}
  }));
})

// This will not throw an error anymore
const api = new API();
knpiaxh1

knpiaxh12#

这最终是由于我从中导出类的文件中的附加代码。

import { store } from "root/App";

if (typeof store !== "undefined") {
  let storeState = store.getState();
  let profile = storeState.profile;
}

在顶部,在我的类之外的一些功能,我一直在努力。
这导致了类默认导出失败,但在Jest中,而不是在我的实际应用程序中。

fkaflof6

fkaflof63#

您需要将其导出为:

export default class API
35g0bw71

35g0bw714#

您可以尝试:

  • 实用程序/API.js*
export default class API {
...
}
  • 测试.js*
import API from "utils/API";

const api = new API();
u5rb5r59

u5rb5r595#

尝试在tsconfig.json中添加"esModuleInterop": true,。默认情况下,esModuleInterop设置为false或未设置。B将esModuleInterop设置为true会更改编译器的行为并修复一些ES6语法错误。请参阅此处的文档。

r8xiu3jd

r8xiu3jd6#

我添加这个是因为我提出的问题是相同的,但有一个稍微不同的设置。
我不会导出默认的类,即
MyClass.ts

// with default
export default MyClass {
   public myMethod()
   {
      return 'result';
   }
}

// without default, which i'm doing in some instances.
export MyClass {
   public myMethod()
   {
      return 'result';
   }
}

如果没有默认值,导入语法将更改。
在一个(开玩笑的)测试中,如果你按照惯例,你确实有export default MyClass(){};
那么下面的工作。

const MOCKED_METHOD_RESULT = 'test-result'
jest.mock("MyClass.ts", () => {
    // will work and let you check for constructor calls:
    return jest.fn().mockImplementation(function () {
        return {
            myMethod: () => {
                return MOCKED_METHOD_RESULT;
            },
   
        };
    });
});

然而,如果你没有default,或者试图模拟其他类等,那么你需要做以下事情。
请注意,{get MyClass(){}}是关键部分,我相信您可以将jest.fn().mockImplementation()替换为jest.fn(()=>{})

jest.mock("MyClass.ts", () => ({
    get MyClass() {
        return jest.fn().mockImplementation(function () {
            return {
               myMethod: () => {
                   return MOCKED_METHOD_RESULT;
               },
   
           };
        });
    },
}));

所以问题在于你访问类内容的方式,get部分允许你正确定义类导出。

bbmckpt7

bbmckpt77#

我使用下面的代码解决了这个错误。

jest.mock('YOUR_API_PATH', () => ({
 __esModule: true,
 default: // REPLICATE YOUR API CONSTRUCTOR BEHAVIOUR HERE BY ADDING CLASS
})

如果你想模拟完整的API类,请检查下面的代码段。

jest.mock('YOUR_API_PATH', () => ({
  __esModule: true,
  default: class {
    constructor(args) {
     this.var1 = args.var1
    }
    someMethod: jest.fn(() => Promise.resolve())
  },
}));

相关问题