问题描述
我正在使用 axios
后调用后端测试我的快速路由器。我收到的是 500
响应而不是 200,不确定如何有效地模拟 multer
。
对此有何想法?谢谢
routes.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',},})
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)
})
})
})