简体   繁体   English

如何在 Jest 中模拟 JSON 文件

[英]How to mock JSON file in Jest

I am using Jest to test my API and when I run my tests, my JSON file results.json gets written to due to the following line in my API app.js (which I don't want happening): I am using Jest to test my API and when I run my tests, my JSON file results.json gets written to due to the following line in my API app.js (which I don't want happening):

fs.writeFile('results.json', JSON.stringify(json), (err, result) => {
    if (err) console.log('error', err);
});

This is what my Jest file looks like:这是我的 Jest 文件的样子:

const request = require('supertest');
const app = require('./app');


// Nico Tejera at https://stackoverflow.com/questions/1714786/query-string-encoding-of-a-javascript-object
function serialise(obj){
    return Object.keys(obj).map(k => `${encodeURIComponent(k)}=${encodeURIComponent(obj[k])}`).join('&');
}


describe('Test /addtask', () => {
    test('POST /addtask Successfully redirects if newDate and newTask filled in correctly', () => {
        const params = {
                    newTask: 'Example',
                    newDate: '2020-03-11'
        };
        return request(app)
            .post('/addtask')
            .send(serialise(params))
            .expect(301);
    });
});

I tried creating a mock of the JSON file and placed it outside the describe statement to prevent the actual results.json file being written to:我尝试创建 JSON 文件的模拟并将其放在describe语句之外以防止实际results.json 。json 文件被写入:

jest.mock('./results.json', () => ({ name: 'preset1', JSONtask: [], JSONcomplete: [] }, { name: 'preset2', JSONtask: [], JSONcomplete: [] }));

But this doesn't change anything.但这并没有改变任何东西。 Does anyone have any suggestions?有没有人有什么建议?

I have seen other solutions to similar problems but they don't provide the answer I'm looking for.我已经看到了类似问题的其他解决方案,但它们没有提供我正在寻找的答案。

EDIT: Although not a very good method, one solution to my problem is to wrap the fs.writeFile within the statement编辑:虽然不是一个很好的方法,但我的问题的一个解决方案是将fs.writeFile包装在语句中

if (process.env.NODE_ENV !== 'test') {
//code
};

although this would mean that fs.writeFile cannot be tested upon.尽管这意味着无法测试fs.writeFile

NOTE: I am still accepting answers!注意:我仍然接受答案!

Your issue is that the code you want to test has a hard-coded I/O operation in it, which always makes things harder to test.您的问题是您要测试的代码中有一个硬编码的 I/O 操作,这总是使事情更难测试。

What you'll want to do is to isolate the dependency on fs.writeFile , for example into something like a ResultsWriter .您要做的是隔离对fs.writeFile的依赖,例如将其隔离到ResultsWriter之类的东西中。 That dependency can then be injected and mocked for your test purposes.然后可以为您的测试目的注入和模拟该依赖项。

I wrote an extensive example on a very similar case with NestJS yesterday under how to unit test a class extending an abstract class reading environment variables , which you can hopefully adapt to your needs.我昨天在如何对扩展抽象 class 读取环境变量的 class 进行单元测试,我写了一个与 NestJS 非常相似的案例的广泛示例,希望您可以适应您的需求。

jest.mock(path, factory) is for mocking JS modules, not file content. jest.mock(path, factory)用于 mocking JS 模块,而不是文件内容。

You should instead mock fs.writeFile and check that it has been called with the expected arguments.您应该改为模拟fs.writeFile并检查它是否已使用预期的 arguments 调用。 The docs explain how to do it. 文档解释了如何做到这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM