node.js - 如何使用 jest/enzyme 模拟 multer 以使用 axios post mock call 进行文件上传
问题描述
我正在通过axios
对后端的调用后测试我的快速路由器。我得到的是500
响应而不是 200,不确定如何multer
有效地模拟。对此有什么想法吗?谢谢
路线.jsx
const axios = require('axios')
const router = express.Router()
const multer = require('multer')
const FormData = require('form-data')
const express = require('express')
const upload = multer({ storage: multer.memoryStorage() }).any()
router.post('/', upload, (req, res) => {
const formData = new FormData()
const { body } = req
req.files.forEach(file => {
formData.append(
'files',
file.buffer,
{
filename: file.originalname
},
file.originalname
)
})
axios
.post('/api/endpoint', formData)
.then(response => {return response
})
.catch(e => {
console.log(e)
})
})
module.exports = router
下面是我的测试用例
routes.jsx.test
const axios = require('axios')
const MockAdapter = require('axios-mock-adapter')
const myroute = require('myroute')
const app = express()
const mock = new MockAdapter(axios)
const request = require('supertest')
const express = require('express')
const bodyParser = require('body-parser')
const multer = require('multer')
jest.mock('multer')
multer.mockImplementation(() => {
return {
any () {
return (req, res, next) => {
req.body = { userName: 'testUser' }
req.files = [
{
originalname: 'sample.name',
mimetype: 'sample.type',
path: 'sample.url'
}
]
return next()
}
}
}
})
app.use(bodyParser.json())
app.use('/', myroute)
describe('sendFiles', () => {
const url = '/api/endpoint'
test('200 response', () => {
const myMockRes = { mykey: 'myVal' }
let formData = new FormData()
const file = new Blob(['somee contents'], { type: 'multipart/form-data' })
formData.append('files', file)
formData.append('userName', 'testUser')
mock.onPost(url).reply(200, myMockRes)
return (
request(app)
.post('/')
.send({ userName: 'testUser', files: [file] })
//.expect('Content-Type', /json/)
.expect(200)
.then(response => {
const { data } = response.body
expect(data).toEqual(myMockRes)
})
)
})
})
错误:
TypeError: Cannot read property 'any' of undefined in routes.jsx
const upload = multer({ storage: multer.memoryStorage() }).any()
解决方案
当你使用 时jest.mock('multer')
,Jest 会自动模拟模块并undefined
在测试中调用它时返回。由于我们也想模拟memoryStorage
和any
方法,我们必须通过将工厂作为第二个参数传递给jest.mock
.
jest.mock('multer', () => {
const multer = () => ({
any: () => {
return (req, res, next) => {
req.body = { userName: 'testUser' }
req.files = [
{
originalname: 'sample.name',
mimetype: 'sample.type',
path: 'sample.url',
buffer: Buffer.from('whatever'), // this is required since `formData` needs access to the buffer
},
]
return next()
}
},
})
multer.memoryStorage = () => jest.fn()
return multer
})
另一个问题是Blob
在 Node.js 中不存在。您可以使用它Buffer.from
来生成一个缓冲区以在请求中发送。
const file = Buffer.from('whatever')
而且你不需要FormData
在测试中使用。
整个代码:
// router.test.js
const axios = require('axios')
const MockAdapter = require('axios-mock-adapter')
const express = require('express')
const app = express()
const mock = new MockAdapter(axios)
const request = require('supertest')
const bodyParser = require('body-parser')
const myroute = require('./router')
jest.mock('multer', () => {
const multer = () => ({
any: () => {
return (req, res, next) => {
req.body = { userName: 'testUser' }
req.files = [
{
originalname: 'sample.name',
mimetype: 'sample.type',
path: 'sample.url',
buffer: Buffer.from('whatever'),
},
]
return next()
}
},
})
multer.memoryStorage = () => jest.fn()
return multer
})
app.use(bodyParser.json())
app.use('/', myroute)
describe('sendFiles', () => {
const url = '/api/endpoint'
test('200 response', () => {
const myMockRes = { mykey: 'myVal' }
const file = Buffer.from('whatever')
mock.onPost(url).reply(200, myMockRes)
return request(app)
.post('/')
.send({ userName: 'testUser', files: [file] })
.expect(200)
.then((response) => {
const { data } = response.body
expect(data).toEqual(myMockRes)
})
})
})
推荐阅读
- python - 缓冲区溢出 - 插入了意外值
- c - 意外的函数行为
- python - 我的 If/Else 语句总是返回“if”结果?
- c# - C# - SQL 中的 Reader 总是返回 false
- c# - Service Fabric .NET Core 2.1 服务通信
- python - 如何将此 AutoCAD VBA 代码翻译成 Python?
- c# - 如何在 Entity Framework Core 中按类别过滤数据?
- java - 传递带有连字符或空格的字符串时,Java getElementById 返回 null
- ibm-mobilefirst - 从 mobilefirst 混合应用程序提交页面
- apache-spark - 具有合并镶木地板文件的 Impala 表的性能问题