嘲笑`文件`开玩笑

the*_*ack 32 jsdom jestjs babel-jest

我正在尝试以开玩笑的方式为我的Web组件项目编写测试.我已经使用了带有es2015预设的babel.我在加载js文件时遇到问题.我已经跟踪了一段代码,其中document对象有一个currentScript对象.但在测试环境中它是null.所以我在想同样的嘲笑.但是jest.fn()并没有真正的帮助.我该如何处理这个问题?

一段代码,其中开玩笑失败.

var currentScriptElement = document._currentScript || document.currentScript;
var importDoc = currentScriptElement.ownerDocument;
Run Code Online (Sandbox Code Playgroud)

我写的测试用例. component.test.js

import * as Component from './sample-component.js';

describe('component test', function() {
  it('check instance', function() {
    console.log(Component);
    expect(Component).toBeDefined();
  });
});
Run Code Online (Sandbox Code Playgroud)

以下是jest抛出的错误

Test suite failed to run

    TypeError: Cannot read property 'ownerDocument' of null

      at src/components/sample-component/sample-component.js:4:39
Run Code Online (Sandbox Code Playgroud)

更新: 根据AndreasKöberle的建议,我添加了一些全球变量,并试图嘲笑如下

__DEV__.document.currentScript = document._currentScript = {
  ownerDocument: ''
};
__DEV__.window = {
  document: __DEV__.document
}
__DEV__.document.registerElement = jest.fn();

import * as Component from './arc-sample-component.js';

describe('component test', function() {
  it('check instance', function() {
    console.log(Component);
    expect(Component).toBeDefined();
  });
});
Run Code Online (Sandbox Code Playgroud)

但没有运气

更新:我没有尝试上面的代码__dev__.还可以将文档设置为全局.

Pat*_*ott 14

与其他人所说的类似,但不要试图自己模拟DOM,只需使用JSDOM:

__mocks __/client.js

import { JSDOM } from "jsdom"
const dom = new JSDOM()
global.document = dom.window.document
global.window = dom.window
Run Code Online (Sandbox Code Playgroud)

然后在你的jest配置中:

"setupFiles": [
  "./__mocks__/client.js"
],
Run Code Online (Sandbox Code Playgroud)


小智 14

我一直在努力为我参与的项目模拟文档。我document.querySelector()在 React 组件内部调用,需要确保它正常工作。最终,这对我有用:

it('should test something', () => {
  const spyFunc = jest.fn();
  Object.defineProperty(global.document, 'querySelector', { value: spyFunc });
  <run some test>
  expect(spyFunc).toHaveBeenCalled()
});
Run Code Online (Sandbox Code Playgroud)


the*_*ack 12

我已经使用setUpFilesjest中的属性解决了这个问题.这将在jsdom之后和每次测试之前执行,这对我来说是完美的.

在Jest配置中设置setupFiles,例如:

"setupFiles": ["<rootDir>/browserMock.js"]


// browserMock.js
Object.defineProperty(document, 'currentScript', {
  value: document.createElement('script'),
});
Run Code Online (Sandbox Code Playgroud)

理想的情况是加载webcomponents.js以填充jsdom.


tct*_*c91 6

如果像我一样,您希望将文档模拟为未定义(例如,用于服务器端/客户端测试),我可以在我的测试套件中使用 object.defineProperty 而不必使用 setupFiles

例子:

beforeAll(() => {
  Object.defineProperty(global, 'document', {});
})
Run Code Online (Sandbox Code Playgroud)


the*_*ide 6

如果您需要为属性定义测试值,则有一种稍微细化的方法。每个属性都需要单独定义,并且还需要使属性writeable

Object.defineProperty(window.document, 'URL', {
  writable: true,
  value: 'someurl'
});
Run Code Online (Sandbox Code Playgroud)

见:https : //github.com/facebook/jest/issues/890

这对我使用 Jest21.2.1和 Node有用v8.11.1


dan*_*ilo 6

这是我的项目中名为super-project 的文件夹super-project的结构:


  • 超级项目
    • 配置
      • __mocks__
        • dom.js
    • 源代码
      • 用户.js
    • 测试
      • 用户.test.js
    • 笑话配置.js
    • 包.json

您需要设置 Jest 以在测试中使用模拟:

dom.js

import { JSDOM } from "jsdom"
const dom = new JSDOM()
global.document = dom.window.document
global.window = dom.window
Run Code Online (Sandbox Code Playgroud)

用户.js

export function create() {
  return document.createElement('table');  
}
Run Code Online (Sandbox Code Playgroud)

用户.test.js

import { create } from "../src/user";

test('create table', () => {
  expect(create().outerHTML).toBe('<table></table>');
});
Run Code Online (Sandbox Code Playgroud)

笑话.config.js

module.exports = {
  setupFiles: ["./config/__mocks__/dom.js"],
};
Run Code Online (Sandbox Code Playgroud)

参考:

您需要创建一个手动模拟:
https://jestjs.io/docs/en/manual-mocks.html

操作 DOM 对象:
https ://jestjs.io/docs/en/tutorial-jquery

笑话配置: https:
//jestjs.io/docs/en/configuration