mock fs.readFile with typescript

huangapple go评论78阅读模式
英文:

mock fs.readFile with typescript

问题

I'm here to help with your code translation. Here's the translated code:

我试图模拟 fs.readFile
```javascript
fs.readFile = jest.fn((_, callback) => callback(null, JSON.stringify('sample')));

我试图测试这个函数:

export const readFileAsynchronously = async (pathToFile: string) => {
  const fullPath = join(__dirname, pathToFile);
  if (existsSync(fullPath)) {
    const fileContent = await readFile(fullPath);
    return fileContent.toString();
  }

  return null;
};

我想测试这个函数而不读取实际文件,是否可能?
测试如下:

test('如果文件存在应返回文件内容', async () => {
    jest.mock('fs');
    const existsSync = () => true;
    fs.existsSync = existsSync;
    fs.readFile = jest.fn((_, callback) => {
      return callback(null, JSON.stringify('sample'));
    });
    jest.mock('path');
    path.join = (path: string) => path;
    const pathToFile = './test.txt';
    const result = await readFileAsynchronously(pathToFile);
    expect(result).toEqual('sample');
  });

但我遇到了一个类型错误:
类型“Mock<any, [_: any, callback: any], any>”中未提供属性“promisify”,而在类型“typeof readFile”中是必需的。

我尝试了另一种变体:

const mockedFs = fs as jest.Mocked<typeof fs>;
const existsSync = () => true;
fs.existsSync = existsSync;
mockedFs.readFile.mockImplementationOnce(
  () =>
    new Promise(function (resolve) {
      return resolve('test');
    }),
);

但我收到了一个错误:
TypeError: mockedFs.readFile.mockImplementationOnce 不是一个函数

我不知道如何解决它。请问能否帮助我?


I hope this helps with your code translation. If you have any further questions or need assistance with specific issues in the code, please feel free to ask.

<details>
<summary>英文:</summary>

I&#39;m trying to mock fs.readFile:

fs.readFile = jest.fn((_, callback) => callback(null, JSON.stringify('sample')));

I&#39; m trying to test this function: 

export const readFileAsynchronously = async (pathToFile: string) => {
const fullPath = join(__dirname, pathToFile);
if (existsSync(fullPath)) {
const fileContent = await readFile(fullPath);
return fileContent.toString();
}

return null;
};

And I want to test this function without reading the real file, is it possible? 
The test is: 

test('should return file content if file exists', async () => {
jest.mock('fs');
const existsSync = () => true;
fs.existsSync = existsSync;
fs.readFile = jest.fn((_, callback) => {
return callback(null, JSON.stringify('sample'));
});
jest.mock('path');
path.join = (path: string) => path;
const pathToFile = './test.txt';
const result = await readFileAsynchronously(pathToFile);
expect(result).toEqual('sample');
});

But I&#39;ve got a type error 
Property `__promisify__` is not presented in type &quot;Mock&lt;any, [_: any, callback: any], any&gt;&quot; and is required in type &quot;typeof readFile&quot;.
I&#39;ve tried one more variant:

const mockedFs = fs as jest.Mocked<typeof fs>;
const existsSync = () => true;
fs.existsSync = existsSync;
mockedFs.readFile.mockImplementationOnce(
() =>
new Promise(function (resolve) {
return resolve('test');
}),
);

But I&#39;ve got an error:

TypeError: mockedFs.readFile.mockImplementationOnce is not a function


I don&#39;t have any idea how to solve it. Please, could you help me? 

</details>


# 答案1
**得分**: 1

首先,`readFile` 不是一个 promise。你需要使用一个回调或者使用一个不同的函数 `readFileSync`。

你的函数实现不正确,下面是修复后的版本:

```typescript
import { join } from 'path';
import { existsSync, readFile } from 'fs';
export const readFileAsynchronously = async (pathToFile: string) => {
  const fullPath = join(__dirname, pathToFile);
  if (existsSync(fullPath)) {
    // 当回调被调用时,使其解析
    return new Promise((resolve, reject) => {
      readFile(fullPath, 'utf8', (error, fileContent) => {
        if (error) return reject(error);
        resolve(fileContent);
      });
    });
  }

  return Promise.reject(new Error('文件未找到'));
};

以下是你的测试实现:

jest.mock('fs', () => ({
  existsSync: jest.fn().mockResolvedValue(true),
  readFile: jest.fn().mockImplementation((path, options, callback) => {
    callback(null, '我的文件内容');
  }),
}));

test('应该在不实际读取文件的情况下解析', async () => {
  const result = await readFileAsynchronously('test.txt');
  expect(result).toBe('我的文件内容');
});
英文:

First of all readFile is not a promise. You need to use a callback or use a different function readFileSync.

Your function is not implemented correctly, here is the fixed version

import { join } from &#39;path&#39;;
import { existsSync, readFile } from &#39;fs&#39;;
export const readFileAsynchronously = async (pathToFile: string) =&gt; {
  const fullPath = join(__dirname, pathToFile);
  if (existsSync(fullPath)) {
    // Making it to resolve when callback is invoked
    return new Promise((resolve, reject) =&gt; {
      readFile(fullPath, &#39;utf8&#39;, (error, fileContent) =&gt; {
        if (error) return reject(error);
        resolve(fileContent);
      });
    });
  }

  return Promise.reject(new Error(&#39;File not found&#39;));
};

And here is your test implementation

jest.mock(&#39;fs&#39;, () =&gt; ({
  existsSync: jest.fn().mockResolvedValue(true),
  readFile: jest.fn().mockImplementation((path, options, callback) =&gt; {
    callback(null, &#39;my file content&#39;);
  }),
}));

test(&#39;should resolve without reading the actual file&#39;, async () =&gt; {
  const result = await readFileAsynchronously(&#39;test.txt&#39;);
  expect(result).toBe(&#39;my file content&#39;);
});

huangapple
  • 本文由 发表于 2023年6月30日 00:39:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/76583018.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定