用Jest单元测试ThreeJS应用程序 [英] Unit testing a ThreeJS application with Jest

查看:46
本文介绍了用Jest单元测试ThreeJS应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很难用Jest测试JavaScript文件,该文件封装了与ThreeJS的许多交互.我首先尝试不模拟ThreeJS,这是行不通的:

I am having difficulties testing a JavaScript file with Jest which encapsulate a lot of interactions with ThreeJS. I first tried not to mock ThreeJS, which did not work :

  ● TestSuite › Should instantiate a renderer attached to a specific element of the DOM

    TypeError: Cannot read property 'getExtension' of null

      36 |      */
      37 |     constructor(containerId: string) {
    > 38 |         this.renderer = new WebGLRenderer({ antialias: true });
      39 |         this.attachRenderer(containerId);
      40 |         this.createCamera();
      41 |         this.createScene();

这很正常,因为我们在没有webgl上下文的类似浏览器的环境中进行测试.因此,我为解决此问题所做的就是模拟Three.js.

That's normal, because we are testing in a browser-like environment which has no webgl context . So what I did to solve this problem was mocking three.js.

然后我用 jest.mock("three");

  ● TestSuite › Should instantiate a renderer attached to a specific element of the DOM

    TypeError: this.renderer.setSize is not a function

      64 |             throw new Error("Cannot find DOM element object matching the specified ID: " + containerId);
      65 |         }
    > 66 |         this.renderer.setSize(window.innerWidth, window.innerHeight);
      67 |         element.appendChild(this.renderer.domElement);
      68 |     }
      69 |

这是预期的行为,因为开玩笑的每个模拟都返回 undefined ,因此 new WebGLRenderer(); 返回 undefined ,而我无法执行任何操作它.

And that's expected behavior, since every mock from jest returns undefined, new WebGLRenderer(); returns undefined and I cannot do anything with it.

我当前的解决方法是在测试文件中定义在ThreeJS中使用的所有内容:

My current work-around is to define everything I uses in ThreeJS in my test file :

jest.mock("three", () => ({
    Scene: class Scene {
        public add(): void {
            return;
        }
    },
    WebGLRenderer: class WebGlRenderer {
        public render(): void {
            return;
        }
        public setSize(): void {
            return;
        }
    }
    // And a lot more...
}));

但是我很清楚这不是最佳解决方案.在那之前,我做过同样的事情,但是在模拟文件/three.js中的文件中( https://jestjs.io/docs/en/manual-mocks ),它也可以正常工作,但不能满足我的需求.

But I am well aware that this is not the optimal solution. Before that I was doing the same thing, but in a file in mocks/three.js ( https://jestjs.io/docs/en/manual-mocks ), which was also working fine but that does not satisfy my need.

有没有一种方法可以正确测试此文件,而不必编写大量的threejs手动模拟?

Is there a way to test this file properly, without having to write tons of manual mocks of threejs ?

推荐答案

我也在webgl上工作,并通过以下方式解决了这个问题. https://github.com/AmitTeli/webgl-three-test

I am also working on webgl this and solved this in following way. https://github.com/AmitTeli/webgl-three-test

该方法的摘要是

  1. 将所有全局变量(例如场景渲染器相机)移动到 index.html
  2. 在加载页面时将其初始化.例如在此reactjs示例中,它们在根组件的 componentDidMount()中初始化.其他功能可以使用此上下文.(您可以通过运行 yarn start 进行检查)
  3. 在进行单元测试时,请在 setupTest.js 中对其进行初始化.我们将需要无头Webgl的其他开发依赖项- gl canvas
  4. 现在使用此设置,我们可以在 App.test.js 中运行测试(您可以通过运行 yarn test 进行检查)
  1. Move all the global variables like scene, renderer and camera to index.html
  2. Initialize them on loading of the page. e.g. in this reactjs example, they are initialized in componentDidMount() of the root component. Other functions can use this context. (You can check this by running yarn start)
  3. While doing the unit testing, initialize them in setupTest.js. We will need additional dev dependencies of headless webgl - gl and canvas
  4. With this setup now we can run the test in say App.test.js (You can check this by running yarn test)

这篇关于用Jest单元测试ThreeJS应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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