如何在一个脚本中监视javascript函数,该脚本被注入jsdom用于测试目的?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在一个脚本中监视javascript函数,该脚本被注入jsdom用于测试目的?相关的知识,希望对你有一定的参考价值。

我正在尝试在开发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 :(
    });
});

我怀疑问题与错误的导入/导出有关,或者注入jsdom的background.js脚本没有被间谍包裹。如果有人能对这个问题有所了解,我真的很感激!

答案

您需要NodeJS上下文中的背景

bg = require('background.js');

然后在你的测试中你应用间谍。

然而,JSDOM通过fs.readFileSync获取了自己的文件副本,并在沙盒中执行它,与NodeJS上下文分开 - 所以你不是在那里应用假的。

除此之外,根据您提供的示例判断,当您加载(或需要)background.js时,searchTabs函数已经执行 - 因此在调用函数后应用间谍将不会获得预期的结果。

你可以做的是将函数与实际执行分开,并在JSDOM沙箱中间应用伪造。这可能看起来像这样:

background.js

window.searchTabs = () => {
  // I'm searching for tabs
}

run.js

window.searchTabs();

test.js

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

如果您正在寻找一种基于manifest.json在JSDOM中加载弹出窗口或背景的简单方法,那么webextensions-jsdom也可能很有趣。

以上是关于如何在一个脚本中监视javascript函数,该脚本被注入jsdom用于测试目的?的主要内容,如果未能解决你的问题,请参考以下文章

使用 inotifywait 监视多个目录并运行脚本

如何在 AIX 中监视没有 cron 作业的文件更改

Shopware 6 如何在监视脚本期间禁用 ESLint?

shell编程之export

如何在 Angular 单元测试中模拟/监视导入的函数

Laravel mix / webpack 不会在通过 babel() 编译的脚本上触发监视功能