我需要测试使用SerialPort的代码。 怎么开玩笑呢?我试图模拟SerialPort并更改write方法的实现:
protocol.js
import SerialPort from 'serialport'
const port = new SerialPort('/dev/ttyS0')
function getCRC(data) {
let crc = 0
for (let i = 0; i < data.length; i++) {
crc ^= data[i]
for (let j = 0; j < 8; j++) {
if (crc & 0x0001) crc = 0x08408 ^ crc >> 1
else crc >>>= 1
}
}
return Array.of(crc & 0xFF, crc >> 8 & 0xFF)
}
function reset() {
let msg = Array.of(0x02, 0x03, 0x06, 0x30)
msg = msg.concat(getCRC(msg))
port.write(msg)
}
export { reset }
protocol.spec.js
import { reset } from './protocol'
import SerialPort from 'serialport'
jest.mock('serialport')
describe('test protocol commands', () => {
beforeAll(() => {
SerialPort.mockImplementation(() => {
return {
write: () => {
throw new Error('test error')
}
}
})
})
it('should throw an error when calling reset command', () => {
expect(() => reset()).toThrow()
})
})
但是它不起作用。如何正确更改实现?
答案 0 :(得分:0)
jest.mock
呼叫被babel-jest
挂起,因此该行首先运行:
jest.mock('serialport')
......会自动将serialport
模块调出。
import
行接下来运行,因此protocol.js
被导入...并且在导入时,该行运行:
const port = new SerialPort('/dev/ttyS0')
...使用port
的空自动模拟实现创建SerialPort
。
然后运行beforeAll
,为SerialPort
创建模拟实现,但这不会影响在port
中创建的protocol.js
,因为它已经创建了。 / p>
有几种方法可以修复它。
您可以延迟创建port
,直到reset
中需要它为止:
function reset() {
let msg = Array.of(0x02, 0x03, 0x06, 0x30)
msg = msg.concat(getCRC(msg))
const port = new SerialPort('/dev/ttyS0') // <= create port here
port.write(msg)
}
您可以使用模块工厂函数来创建模拟:
import { reset } from './protocol'
jest.mock('serialport', () => {
class MockSerialPort {
write() {
throw new Error('test error')
}
}
return MockSerialPort;
});
describe('test protocol commands', () => {
it('should throw an error when calling reset command', () => {
expect(() => reset()).toThrow() // Success!
})
})
或者您可以在write
的{{1}}上嘲笑prototype
:
SerialPort