Javascript 摩卡咖啡的副作用

Javascript 摩卡咖啡的副作用,javascript,mocha.js,Javascript,Mocha.js,我目前正在尝试在javascript中运行测试套件时插入一些代码,但在使用mocha时实际吐出数据时遇到了问题 似乎当我试图打印一些东西(甚至写入文件)时,我没有成功 请参见下面的示例: main.js lib.js test.js 结果应该创建一个名为test\u file的文件,其内容为hello world 我创建了一个存储库,其中包含可以轻松克隆和测试的完整示例 在测试文件中,您正在导入main。但是main只是您在main.js:函数(a){returna+1}中导出的内容 您应该导出

我目前正在尝试在javascript中运行测试套件时插入一些代码,但在使用mocha时实际吐出数据时遇到了问题

似乎当我试图打印一些东西(甚至写入文件)时,我没有成功

请参见下面的示例:

main.js lib.js test.js 结果应该创建一个名为
test\u file
的文件,其内容为
hello world

我创建了一个存储库,其中包含可以轻松克隆和测试的完整示例


在测试文件中,您正在导入
main
。但是
main
只是您在
main.js
函数(a){returna+1}
中导出的内容

您应该导出整个文件:

var Foo = require('./lib')

module.exports = function(a) { 
  Foo();
  return a + 1;
}

不知道Mocha到底是如何工作的(即它如何管理测试的线程池,甚至它是否拥有该池),但看起来Mocha在测试完成后会杀死线程

所以setTimeout不会触发事件,因为线程已经死了


(而setTimeout(…,1)将触发事件-只需尝试一下即可)

根本问题是,像您这样使用
done
是行不通的。Mocha进入您的测试,执行它,然后立即调用
done
。所以摩卡认为它已经完成并退出了

还有一个事实是
lib.js
的设计很糟糕。您可以这样实现它:

const fs = require('fs');
module.exports = function(cb) {
    setTimeout(function() {
        fs.writeFile('test_file', 'hello world', cb);
        console.log('hello finished');
    }, 1000);

    console.log('hello begin');
};
我刚刚将
cb
参数添加到导出的函数中,并将其传递给
fs.writeFile

最低限度检查正确文件的测试将执行以下操作:

const fs = require("fs");
const lib = require("./lib");
const assert = require("assert");
describe("some test", function() {
    it("should do something", function(done) {
        lib(function (err) {
            if (err) {
                done(err);
            }

            fs.readFile("./test_file", function (err, data) {
                if (err) {
                    done(err);
                }

                assert.equal(data, "hello world");
                done();
            });
        });
    });
    after(function (done) {
        fs.unlink("./test_file", function () {
            // We don't want a cascading failure here if the test
            // above failed to create the file so we ignore errors
            // here.
            done();
        });
    });
});

请注意我是如何直接在上面测试
lib.js
。单元测试就是这样工作的。测试最小的功能单元。然后您可以编写一个测试来检查
main.js
是否调用了由
lib.js

导出的函数,这就是我想要的。你不知道如何让摩卡停止杀线,是吗?不知道。听起来像是“如何打破摩卡”。对我来说,看起来你设计的测试很糟糕——我的意思是,如果你想在等待一段时间后检查一些东西,那么你就不应该在那之前完成()测试。本质上,我正在尝试为一个使用mocha运行测试的第三方库提供工具(测试是正常的)。我希望在运行时收集数据,然后在所有测试运行后将其输出到stout。我一点也不关心测试的质量。你可以在某个对象上总结结果,然后在after()/afterEach()钩子上打印出来——这正是你要做的。但是为什么你需要setTimeout,我仍然无法理解。虽然我同意这是更好的设计,但我提供的示例是一个最小的示例(不一定是一个模型示例)。请看@Artem的答案,他为我指出了正确的方向,但不知道解决这个问题所需的全部细节。这个答案是不正确的。这其中没有任何“线索”。如果答案不正确,那么你能解释一下为什么事件从未发生过吗?第一段:“所以摩卡认为它已经完成并退出了。”这就是为什么事件从未发生过。
var Foo = require('./lib')

module.exports = function(a) { 
  Foo();
  return a + 1;
}
const fs = require('fs');
module.exports = function(cb) {
    setTimeout(function() {
        fs.writeFile('test_file', 'hello world', cb);
        console.log('hello finished');
    }, 1000);

    console.log('hello begin');
};
const fs = require("fs");
const lib = require("./lib");
const assert = require("assert");
describe("some test", function() {
    it("should do something", function(done) {
        lib(function (err) {
            if (err) {
                done(err);
            }

            fs.readFile("./test_file", function (err, data) {
                if (err) {
                    done(err);
                }

                assert.equal(data, "hello world");
                done();
            });
        });
    });
    after(function (done) {
        fs.unlink("./test_file", function () {
            // We don't want a cascading failure here if the test
            // above failed to create the file so we ignore errors
            // here.
            done();
        });
    });
});