Javascript 如何在';为了测试的目的,将什么注入jsdom?
我试图在开发chrome扩展时测试功能。对于我的测试框架,我正在使用sinon(间谍、模拟和存根)、mocha、chai和jsdom(创建一个执行chrome扩展背景和弹出脚本的dom) 但是,我似乎无法监视我正在注入jsdom的脚本(background.js)中的函数 这就是我正在做的: background.jsJavascript 如何在';为了测试的目的,将什么注入jsdom?,javascript,unit-testing,google-chrome-extension,sinon,jsdom,Javascript,Unit Testing,Google Chrome Extension,Sinon,Jsdom,我试图在开发chrome扩展时测试功能。对于我的测试框架,我正在使用sinon(间谍、模拟和存根)、mocha、chai和jsdom(创建一个执行chrome扩展背景和弹出脚本的dom) 但是,我似乎无法监视我正在注入jsdom的脚本(background.js)中的函数 这就是我正在做的: background.js function searchTabs() {...} searchTabs(); module.exports.searchTabs = searchTabs; back
function searchTabs() {...}
searchTabs();
module.exports.searchTabs = searchTabs;
background.test.js
var fs = require('fs');
var sinon = require('sinon');
var chrome = require('sinon-chrome');
var assert = require('chai').assert;
var jsdom = require('jsdom');
var bg = require('background.js');
var window;
var spy;
describe('background page', function () {
beforeEach(function () {
jsdom.env({
html: '<html></html>',
src: [
fs.readFileSync('background.js', 'utf-8'), // Inject script into jsdom
],
created: ...,
done: ...,
});
});
afterEach(function () {
chrome.reset();
window.close();
});
it('should call searchTabs', function () {
spy = sinon.spy(bg.searchTabs);
sinon.assert.calledOnce(spy); // This is not called :(
});
});
var fs=require('fs');
var sinon=要求(“sinon”);
var chrome=要求('sinon-chrome');
var assert=require('chai')。assert;
var jsdom=require('jsdom');
var bg=require('background.js');
var窗口;
var-spy;
描述('背景页',功能(){
beforeach(函数(){
jsdom.env({
html:“”,
src:[
fs.readFileSync('background.js','utf-8'),//将脚本注入jsdom
],
创建:。。。,
完成:。。。,
});
});
在每个(函数()之后){
chrome.reset();
window.close();
});
它('应该调用searchTabs',函数(){
spy=sinon.spy(bg.searchTabs);
sinon.assert.calledOnce(spy);//这不是调用的:(
});
});
我怀疑这个问题与不正确的导入/导出有关,或者注入jsdom的background.js脚本没有被spy包装。如果有人能解释一下这个问题,我将不胜感激!您在NodeJS上下文中需要背景
bg = require('background.js');
然后在你的测试中,你用一个间谍
然而,JSDOM通过fs.readFileSync
获取自己的文件副本,并在沙箱中执行它,与NodeJS上下文分离,因此您没有在那里应用伪代码
除此之外,从您提供的示例判断,当您加载(或需要)background.js时,searchTabs
函数已经执行了,因此在调用函数后应用spy不会得到预期的结果
相反,您可以将函数从实际执行中分离出来,并在JSDOM沙盒内部,在两者之间应用赝品
background.js
function searchTabs() {...}
searchTabs();
module.exports.searchTabs = searchTabs;
run.js
test.js
const fs=require('fs');
const chrome=require('sinon-chrome');
const{JSDOM}=require('JSDOM');
常量html='';
const dom=新的JSDOM(html{
运行脚本:“仅限外部”,
beforeParse(窗口){
window.chrome=chrome;
}
});
eval(fs.readFileSync('background.js');
const spy=sinon.spy(dom.window,'searchTabs');
eval(fs.readFileSync('run.js');
sinon.assert.calledOnce(间谍);
如果您正在寻找一种基于manifest.json在JSDOM中加载弹出窗口或背景的简单方法,那么可能也会很有趣。我怀疑以下内容可能会有所启发:请回答主题中的问题:包括一个重复问题的问题。对于Chrome扩展或Firefox WebExtensions,您几乎总是需要包括您的人ifest.json和一些背景、内容和/或弹出脚本/HTML,通常还有网页HTML/scripts。寻求调试帮助的问题(“为什么我的代码不能按我想要的方式工作?”)必须包括:(1)所需的行为,(2)特定的问题或错误,以及(3)在问题本身中复制它所需的最短代码。另请参见:,和。
window.searchTabs();
const fs = require('fs');
const chrome = require('sinon-chrome');
const {JSDOM} = require('jsdom');
const html = '<!DOCTYPE html><html><head></head><body></body></html>';
const dom = new JSDOM(html, {
runScripts: 'outside-only',
beforeParse(window) {
window.chrome = chrome;
}
});
dom.window.eval(fs.readFileSync('background.js'));
const spy = sinon.spy(dom.window, 'searchTabs');
dom.window.eval(fs.readFileSync('run.js'));
sinon.assert.calledOnce(spy);