【问题标题】:Mocha / Sinon - Unit testing / stubbing function with child_process.exec inside ES6 PromiseMocha / Sinon - 在 ES6 Promise 中使用 child_process.exec 进行单元测试/存根函数
【发布时间】:2017-06-05 20:03:29
【问题描述】:

我有一个函数可以返回一个 ES6 承诺,以便在另一个外部承诺链中使用。该函数使用 child_process.exec 扫描 wifi 网络。 exec 的输出通过回调发送到同步解析函数,该函数将以格式化对象的形式返回输出,然后解析外部 promise:

var exec = require('child_process').exec;

function scan() {
    return new Promise((resolve, reject) => {

        // getCurrent returns a promise
        getCurrent().then(network => {
            exec('iwlist wlan0 scan', function(err, stdout, stderr) {
                (err) ? reject(stderr) : resolve(parseOutput(stdout, network));                 
            });
        })
        .catch(err => {
            reject(err);
        }); 
    }); 
}

问题是,我似乎无法让 sinon 存根正常工作以调用 exec 的存根版本。目前我有一些类似的东西:

var wifi = require('./wifi');

describe('#scan', function() {

    it('Should scan and return networks object', function() {

        var fakeNetwork = '(fake iwlist output goes here)';  
        var exec = sinon.stub(child_process, 'exec').yields(false, fakeNetwork);
        var getCurrent = sinon.stub(wifi, 'getCurrent').returns(Promise.resolve('current-ssid'));

        wifi.scan().then(function(networks) {
            console.log(networks);
            sinon.assert.calledOnce(getCurrent);
            sinon.assert.calledOnce(exec);
        });

        getCurrent.restore();
        exec.restore();

    });
});

我也尝试过像这样的存根:

var getCurrent = sinon.stub(wifi, 'getCurrent', function() {
    return Promise.resolve('current-ssid').then(network => {
        exec('iwlist wlan0 scan', function(err, data) {
            return(wifi.parseOutput(data, network));                
        });
    });
});

这种行为似乎是 exec 永远不会被调用,或者更奇怪的是,存根的 exec 确实被调用了,但“真正的”函数无论如何都会被调用。

对于所有的存根,我真正“测试”的只是 parseOutput 方法,所以我是否应该完全放弃测试“扫描”函数而只关注解析函数(这很容易测试),或者还有另一种方法我应该看看这个吗?

我相信我只是在做一些明显错误的事情,并且已经在这里碰壁了几个小时。我希望有人以前遇到过这种情况并可以提出替代/更好的方法。

【问题讨论】:

    标签: javascript unit-testing mocha.js sinon


    【解决方案1】:

    你可以使用 stub.yields([arg1, arg2, ...]) sinon stubs guide

    这是我的代码

    function getVersioniList() {
        let versionList = new Promise((resolve, reject) => {
            child_process.exec(cmd, function(error, stdout, stderr) {
                if (error) {
                    reject(error);
                }
                resolve(stdout);
            });
        });
    
        return versionList;
    }
    

    单元测试代码如下

    // i like the sandbox, or you can use sinon itself
    sandbox = sinon.sandbox.create();
    sandbox.stub(child_process, 'exec').yields(undefined, [1, 2, 3]);
    
    assert.equal(await getVersioniList(), [1, 2, 3]);
    

    终于可以得到versionList [1, 2, 3]

    【讨论】:

      猜你喜欢
      • 2016-05-26
      • 2019-05-24
      • 1970-01-01
      • 2021-11-26
      • 2019-02-14
      • 1970-01-01
      • 2019-10-13
      • 1970-01-01
      • 2021-09-27
      相关资源
      最近更新 更多