Макет SerialPort с шуткой - PullRequest
0 голосов
/ 24 мая 2019

Мне нужно проверить код, работающий с SerialPort.Как это сделать с шуткой?Я попытался смоделировать SerialPort и изменить реализацию метода записи:

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()
  })
})

Но это не работает.Как правильно изменить реализацию?

1 Ответ

0 голосов
/ 25 мая 2019

jest.mock вызовы подняты на babel-jest, поэтому эта строка запускается первой:

jest.mock('serialport')

..., которая автоматически моделирует модуль serialport.

importДалее следуют строки, поэтому protocol.js импортируется ... и когда импортируется, эта строка запускается:

const port = new SerialPort('/dev/ttyS0')

..., которая создает port с использованием пустой автоматической моделируемой реализации SerialPort.

Затем запускается beforeAll, который создает фиктивную реализацию для SerialPort, но это не влияет на port, созданный в protocol.js, поскольку он уже создан.


Есть несколько способов исправить это.

Вы можете отложить создание 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 на prototype из SerialPort:

import { reset } from './protocol'
import SerialPort from 'serialport'

jest.mock('serialport')

describe('test protocol commands', () => {
  beforeAll(() => {
    const mock = jest.spyOn(SerialPort.prototype, 'write');
    mock.mockImplementation(() => {
      throw new Error('test error')
    });
  })

  it('should throw an error when calling reset command', () => {
    expect(() => reset()).toThrow()  // Success!
  })
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...