如何在Jest中测试一个不是模块的类?

gijlo24d  于 2023-05-04  发布在  Jest
关注(0)|答案(1)|浏览(143)

我有一个文件MyClass.js,我需要在HTML中同步加载,所以我删除了export代码,因为使用<script>type="module"属性加载模块是异步的。这解决了我在应用程序中使用类的问题。
现在的问题是,我不能在Jest测试套件中导入这个类,因为我最初是将它作为模块导入的,现在它不再是模块了。似乎无论我做什么,MyClass最终都是undefined。我已经验证了文件的路径是正确的。
我尝试过的:

  • 加载代码并使用eval()解析它。我不知道为什么这不起作用:
const myClassCode = fs.readFileSync('./js/myClass.js', 'utf-8');
eval(myClassCode);
  • 基本的import或require语句。我相信这两个都要求MyClass.js是一个模块。
  • 在沙箱中提取代码,然后将类拉回到测试中:
const classFileContent = fs.readFileSync(path.resolve(__dirname, '../MyClass.js'), 'utf-8');

// Create a new context with a global object.
const context = {
  MyClass: undefined,
};
vm.createContext(context);

// Run the class file content in the created context.
vm.runInContext(classFileContent, context);

// Get the class from the context.
const MyClass= context.MyClass;

我想这一定是一个普通的任务,应该是微不足道的,但我只是没有看到将这个类导入到我的测试中的简单解决方案。将MyClass.js重新更改为模块不是一个选项,因为这会破坏我的实际应用程序。我对js很陌生,所以我猜我在这里忽略了一些东西。有人能给我指个方向吗?

aydmsdu9

aydmsdu91#

**警告!我建议不要在生产代码中使用这种技术,如果使用不当,eval()可能会使您的应用程序面临严重的安全风险。在我的情况下,我使用它进行测试,你已经被警告!

我能够使用eval()解决这个问题,但我必须做一些修改。
看起来eval()在它自己的作用域内创建了这个类,但是这个类仍然在调用eval()的脚本的作用域之外。为了解决这个问题,我们需要在eval()中设置一个赋值给MyClass
而不是:

const myClassCode = fs.readFileSync('./js/myClass.js', 'utf-8');
eval(myClassCode);

用途:

let myClassCode = fs.readFileSync('./js/myClass.js', 'utf-8');
myClassCode = 'MyClass = (' + myClassCode+ ')';
eval(myClassCode);

这不仅解析了myClass.js中的类,还将其分配给作用域中的变量MyClass,然后可以使用该变量调用类函数。

相关问题