Jestjs 开玩笑地嘲笑“文件”
我试图开玩笑地为我的web组件项目编写测试。我已经在es2015预设中使用了巴贝尔。我在加载js文件时遇到了一个问题。我遵循了一段代码,其中Jestjs 开玩笑地嘲笑“文件”,jestjs,jsdom,babel-jest,Jestjs,Jsdom,Babel Jest,我试图开玩笑地为我的web组件项目编写测试。我已经在es2015预设中使用了巴贝尔。我在加载js文件时遇到了一个问题。我遵循了一段代码,其中document对象有一个currentScript对象。但在测试上下文中,它是null。所以我想嘲弄他们。但是jest.fn()在这方面并没有真正的帮助。我如何处理这个问题 jest失败的代码段 var currentScriptElement = document._currentScript || document.currentScript; var
document
对象有一个currentScript
对象。但在测试上下文中,它是null
。所以我想嘲弄他们。但是jest.fn()
在这方面并没有真正的帮助。我如何处理这个问题
jest失败的代码段
var currentScriptElement = document._currentScript || document.currentScript;
var importDoc = currentScriptElement.ownerDocument;
我写的测试用例<代码>组件.test.js
import * as Component from './sample-component.js';
describe('component test', function() {
it('check instance', function() {
console.log(Component);
expect(Component).toBeDefined();
});
});
下面是jest抛出的错误
Test suite failed to run
TypeError: Cannot read property 'ownerDocument' of null
at src/components/sample-component/sample-component.js:4:39
更新:
根据Andreas Kö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();
});
});
但是没有运气
更新:我在没有
的情况下尝试了上述代码。另外,通过将文档设置为全局。我在jest中使用了setUpFiles
属性解决了这个问题。这将在jsdom之后和每个测试之前执行,这对我来说非常完美
在Jest配置中设置设置文件,例如:
"setupFiles": ["<rootDir>/browserMock.js"]
// browserMock.js
Object.defineProperty(document, 'currentScript', {
value: document.createElement('script'),
});
“setupFiles”:[“/browserMock.js”]
//browserMock.js
Object.defineProperty(文档“currentScript”{
值:document.createElement('script'),
});
理想的情况是加载webcomponents.js来填充jsdom。我可以使用nodejs上的global
scope模块解决同样的问题,用mock of document设置document,在我的例子中,getElementsByClassName
:
// My simple mock file
export default {
getElementsByClassName: () => {
return [{
className: 'welcome'
}]
}
};
// Your test file
import document from './name.component.mock.js';
global.document = {
getElementsByClassName: document.getElementsByClassName
};
如果像我一样,您希望将文档模拟为未定义(例如,对于服务器端/客户端测试),我可以在测试套件中使用object.defineProperty,而不必使用setupfile
例如:
beforeAll(() => {
Object.defineProperty(global, 'document', {});
})
如果您需要为属性定义测试值,有一种更精细的方法。每个属性都需要单独定义,还需要使属性可写:
Object.defineProperty(window.document, 'URL', {
writable: true,
value: 'someurl'
});
见:
我使用Jest21.2.1
和Nodev8.11.1
与其他人所说的类似,但不要试图自己模仿DOM,只需使用JSDOM:
模拟/client.js
从“JSDOM”导入{JSDOM}
constdom=newjsdom()
global.document=dom.window.document
global.window=dom.window
然后在您的玩笑配置中:
“设置文件”:[
“/\uuuu mocks\uuuu/client.js”
],
我一直在为正在进行的项目模拟文档而奋斗。我正在React组件内部调用document.querySelector()
,需要确保它工作正常。归根结底,这对我来说是有效的:
it('should test something', () => {
const spyFunc = jest.fn();
Object.defineProperty(global.document, 'querySelector', { value: spyFunc });
<run some test>
expect(spyFunc).toHaveBeenCalled()
});
it('应该测试一些东西',()=>{
const spyFunc=jest.fn();
defineProperty(global.document,'querySelector',{value:spyFunc});
expect(spyFunc).toHaveBeenCalled()
});
希望这有帮助
const wrapper = document.createElement('div');
const render = shallow(<MockComponent{...props} />);
document.getElementById = jest.fn((id) => {
wrapper.innerHTML = render.find(`#${id}`).html();
return wrapper;
});
const wrapper=document.createElement('div');
const render=shallow();
document.getElementById=jest.fn((id)=>{
wrapper.innerHTML=render.find(`${id}`).html();
返回包装器;
});
这是我的名为super-project的项目中文件夹super-project中的结构:
- 超级项目
- 配置
\uuuuu mocks\uuuuu
- dom.js
- src
- user.js
- 测验
- user.test.js
- jest.config.js
- package.json
您需要设置Jest以在测试中使用模拟:
dom.js:
从“JSDOM”导入{JSDOM}
constdom=newjsdom()
global.document=dom.window.document
global.window=dom.window
user.js:
导出函数create(){
返回document.createElement('table');
}
user.test.js:
从“./src/user”导入{create};
测试('创建表',()=>{
expect(create().outerHTML).toBe(“”);
});
jest.config.js:
module.exports={
setupFiles:[”/config/\uuuuuu mocks\uuuuuu/dom.js“],
};
参考文献: 您需要创建一个手动模拟:
操作DOM对象:
Jest配置:
我找到了另一个解决方案。假设在组件内部,您希望通过类名(document.getElementsByClassName)获取对DOM中元素的引用。您可以执行以下操作:
let wrapper
beforeEach(() => {
wrapper = mount(<YourComponent/>)
jest.spyOn(document, 'getElementsByClassName').mockImplementation(() =>
[wrapper.find('.some-class').getDOMNode()]
)
})
let包装器
在每个之前(()=>{
包装器=mount()
jest.spyOn(文档'getElementsByClassName').mockImplementation(()=>
[wrapper.find('.some class').getDOMNode()]
)
})
通过这种方式,您可以手动将getElementsByClassName的返回值设置为.some类的引用。可能需要通过调用wrapper.setProps({})重新加载组件
希望这对你们中的一些人有所帮助 你试过使用
global.document
吗?是的。我试过了。运气不好。所以我基本上使用了jsdom,比如constJSDOM=require('jsdom');const documentHTML='';global.document=jsdom.jsdom(documentHTML)代码>之后,我将添加任何我想要的内容到文档中,并在测试中使用它。实际上,这里的问题是,jsdom非常简单,没有webcomponents API。总之,根据我的回答,暂时解决了这个问题。是的,但它的用例非常简单……在webcomponents.js中,我们有大量的API相互连接。模拟它们是一项非常艰巨的任务…但是在你的情况下,你到底需要模拟什么?我试图通过在对象中提供它们来模拟document.referer
和document.URL
。运气不好。属性仍然在test runner中显示为它们的常规值。@theUtherSide我注意到此解决方案在某些版本的Node中工作,而在其他版本中不工作。也许可以安装NVM并玩不同版本的游戏谢谢你的提示!我要和诺德玩