Javascript 如何在';为了测试的目的,将什么注入jsdom?

Javascript 如何在';为了测试的目的,将什么注入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

我试图在开发chrome扩展时测试功能。对于我的测试框架,我正在使用sinon(间谍、模拟和存根)、mocha、chai和jsdom(创建一个执行chrome扩展背景和弹出脚本的dom)

但是,我似乎无法监视我正在注入jsdom的脚本(background.js)中的函数

这就是我正在做的:

background.js

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);