无法在Node.js单元测试中模拟文件系统 [英] Cannot mock filesystem in nodejs unit tests

查看:100
本文介绍了无法在Node.js单元测试中模拟文件系统的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用nodejs编写的简单模块,该模块使用fs-extra包测试文件是否存在.当路径存在时,模块将抛出该异常,否则将继续执行下一个过程.这是源文件:

I have a simple module written in nodejs that uses fs-extra package to test if a file exists. The module throws when the path exists and proceed to next procedure otherwise. Here is the source file:

// - main.js -
import fs from 'fs-extra'

export default async (pathName) => {
  // Do not procceed if path already exists.
  if (await fs.pathExists(projectPath)) {
    throw new Error(chalk.red.bold(`${projectPath} already exists`))
  }

  // more logic here
}

我想编写一个测试波纹管逻辑的单元测试:

I want to write a unit test that tests the bellow logic:

  • 如果文件路径存在,我们希望抛出错误

我不想弄乱实际的文件系统(以防我的代码包含一些可能破坏它的讨厌的错误),所以我转到了另一种解决方案,使用mock-fs模拟文件系统.这是规格文件:

I don't want to mess up with the real filesystem -in case my code contains some nasty bug that could destroy it- so I went to an alternative solution, mocking the filesystem using mock-fs. Here is the spec file:

// - main.js spec file -
import mainFunction from '../main'
import mockfs from 'mock-fs'

describe('test main function', () => {
  beforeEach(() => {
    mockfs({
      home: {
        user: {
          dummy: {}
        }
      }
    })
  })

  test('expect to throw', async () => {
    await mainFunction('/home/user/dummy')
  })

  afterEach(() => {
    mockfs.restore()
  })
})

出什么问题了?

每次运行测试时,主函数都不会抛出.发生这种情况是因为在规范文件中声明了mockfs伪文件系统,因此主源文件中的fs模块不知道mockfs伪文件系统,并检查了真实文件系统.在我的真实文件系统中没有名为/home/user/dummy的文件夹时,检查始终失败.

What's the problem?

Every time I run the test, the main function does not throw. This happens because mockfs fake-filesystem was declared in the spec file, so the fs module in main source file does not know for the mockfs fake-filesystem and checks the real one. By the time that I do not have a folder named /home/user/dummy in my real filesystem the check always fails.

mainFunction应该抛出

mainFunction不会抛出

我想我可以将这个单元测试变成一个集成测试.但我不想.有没有解决办法?我是否必须使用其他软件包? 我的测试服是 Jest 22.3.0 .

I guess that I can turn this unit test into an integration test. But I do not want to. Is there any fix for this? Do I have to use another packages? My test suit is Jest 22.3.0.

推荐答案

经过一番搜索,我找到了对分支进行单元测试的适当方法.我们确实不必使用mock-fs模块.我们只需要模拟fs-extra模块的pathExists方法来返回值false一次和值true一次.贝娄,我发布了我的规格文件的工作版本:

After some search, I found the appropriate way to unit test the branch. We really do not have to use the mock-fs module. We just have to mock pathExists method of fs-extra module to return one time the value false and one time the value true. Bellow, I post a working version of my spec file:

import mainFunction from '../main'

require('fs-extra').pathExists = jest.fn().mockReturnValueOnce(false).mockReturnValueOnce(true)

describe('test main function', () => {
  beforeEach(() => {
    jest.clearAllMocks()
  })

  test('expect to not throw', async () => {
    await expect(mainFunction('/dummy/path/does/not/matter')).resolves
  })

  test('expect to throw', async () => {
    await expect(mainFunction('/dummy/path/does/not/matter')).rejects.toBeInstanceOf(Error)
  })
})

这篇关于无法在Node.js单元测试中模拟文件系统的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆