Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/39.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js Jest-函数fs.writefile中的模拟回调_Node.js_Callback_Jestjs_Mocking - Fatal编程技术网

Node.js Jest-函数fs.writefile中的模拟回调

Node.js Jest-函数fs.writefile中的模拟回调,node.js,callback,jestjs,mocking,Node.js,Callback,Jestjs,Mocking,我在这个话题上结巴了3个小时。在此代码中,我找不到如何测试if(err)分支的解决方案: function createFile(data){ return new Promise(function(resolve, reject) { try { if(data === null || data === undefined){ throw new Error(errorMessages.noDataDefined);

我在这个话题上结巴了3个小时。在此代码中,我找不到如何测试if(err)分支的解决方案:

    function createFile(data){

return new Promise(function(resolve, reject) {

    try {

        if(data === null || data === undefined){
            throw new Error(errorMessages.noDataDefined);
        }

        let internalJobId = uuid.v4();
        let fileName = 'project_name' + internalJobId + '.xml';

        fs.writeFile(config.tmpPath + fileName, data, function (err) {
            if (err){
                throw new Error(err.toString());
            } else {
                resolve(fileName);
            }
            
        });

    } catch (error) {
        return reject(error);
    }
});
}

此测试通过,但它不调用if(err){throw new Error(err.toString())}

我必须找到一个解决方案,回调如何返回错误,但我没有得到正确的解决方案

test('Error', () => {

    jest.mock('fs', () => ({
        writeFile: jest.fn((path, data, callback) => callback(Error('some error')))
      }));

    return expect(createFile('Does not matter')).rejects.toThrow('some error');


});

但是这个测试甚至没有拒绝,所以永远不会抛出错误。如果有人能帮助我,我将不胜感激。

这里有两个问题。一个是没有正确地模拟
fs.writeFile
。另一个原因是
createFile
无法正确处理错误,无法满足预期

jest.mock
影响尚未导入并提升到块顶部(或在顶层使用时高于导入)的模块。如果已导入使用它的模块,则它不会影响fs。由于
fs
函数通常与其命名空间一起使用,因此也可以将其模拟为方法

它应该是:

// at top level
import fs from 'fs';
jest.mock('fs', ...);
...
或:

并被断言为使测试更具体:

expect(fs.writeFile).toBeCalledTimes(1);
expect(fs.writeFile).toBeCalledWith(...);
return expect(createFile('Does not matter'))...
Promise构造函数不需要try..catch,因为它已经捕获了其中的所有同步错误,并且无法从回调中捕获异步错误。对于需要拒绝承诺的地方,
拒绝
可以作为一致性的首选

fs.writeFile
回调中抛出错误是一个错误,会导致挂起的承诺。它没有机会拒绝承诺,也没有机会在回调之外被捕获到
try..catch
,并导致未捕获的错误

应该是:

function createFile(data){
    return new Promise(function(resolve, reject) {
        if(data === null || data === undefined){
            reject(new Error(errorMessages.noDataDefined));
        }

        let internalJobId = uuid.v4();
        let fileName = 'project_name' + internalJobId + '.xml';

        fs.writeFile(config.tmpPath + fileName, data, function (err) {
            if (err){
                reject(new Error(err.toString()); // reject(err) ?
            } else {
                resolve(fileName);
            }            
        });
    });
}
为了将嵌套保持在最小程度,可以将不需要promisification的部分移到构造函数外部,函数为
async

async function createFile(data){
    if(data === null || data === undefined){
        throw new Error(errorMessages.noDataDefined);
    }

    return new Promise(function(resolve, reject) {    
        let internalJobId = uuid.v4();
        ...
还有一些可能不需要承诺的问题

还要注意,
newerror(err.toString())
可能是不必要的,并且会导致意外的错误消息,因此断言会失败。承诺可以按原样以
err
拒绝。如果目的是删除不必要的错误信息或更改错误堆栈,则应该是
新错误(err.message)

解决方案是:

 jest.spyOn(fs, 'writeFile').mockImplementation((f, d, callback) => {
                callback('some error');
 });
    

多亏了埃斯特斯

请提供可以重现问题的。您省略了相关的代码片段。没有创建文件。如果将fs.writeFile包装为
新承诺
,则会出现错误,因为在fs.writeFile回调中抛出错误不会导致拒绝承诺。您好,我已更新了此问题。我正在检查错误,抛出此错误,并在catch块中拒绝该错误。感谢您的帮助。我以删除try/catch块的方式更改了代码。另外,第一个if语句位于promise之上,位于异步func now中。但是所有的更改都使代码更干净,但是对于我的第一个问题,似乎仍然没有任何更改。我仍然无法模拟这样一个函数:“reject(新错误(err.toString());//reject(err)?”被涵盖。我不知道,如果这只是对我来说,但我是一个新的笑话,发现模仿的部分比开发的大部分部分更复杂。这是问题的一部分,你可能还没有经历过。我更新了。这不是很难,但可能需要知道它是如何与节点模块混乱的,以及在引擎盖下使用I不幸的是,这个“jest.spyOn('fs','writeFile').mockImplementation(…);”导致“无法监视原语值;字符串给定”这是一个输入错误,已修复。不客气。请注意,这是一个不符合要求的模拟,无法发现错误处理中描述的问题,因为它同步触发错误,而writeFile是异步的。应该是
=>setTimeout(()=>{callback('some error'))
。好的,谢谢。我已经更改了代码。这两种情况下的覆盖率都是100%,但我知道这更符合要求。所以我现在很乐意尝试使用s3 Api,我认为这是一件容易的事情。我必须开玩笑地学习很多东西,但我希望有一天我会正确理解一切;)
 jest.spyOn(fs, 'writeFile').mockImplementation((f, d, callback) => {
                callback('some error');
 });