How to properly unit test with mock bindings
See original GitHub issueSummary of Problem
I’m having a bit of trouble trying to get a unit test of this going. Basically, I have an “adapter” that wraps a serial port (ultimately running on an embedded Linux device). Right now, my firmware team is still working on their end of things, but we have some agreed upon commands, so I am trying to mock out their device, and then test that when I invoke functions in my adapter, that under the covers it creates buffers correctly and passes them over to the device. This will allow me to have a unit test that we can run that will all be green. They can then code up their firmware and run my integration test target and be red. As they code up firmware and get it to respond in the agreed upon format, their tests should slowly turn from red to green – and if there is a discrepancy we can look at what I thought was supposed to happen (in the unit test), and compare it to the response from the actual device (integration test).
I turned on the echo feature so that my serial port will echo back the input data. Maybe the write
event is simply the wrong event to be listening to? I’m trying to dig in and see exactly what happens in that scenario, but I’ll keep trying to look into it (hopefully while someone can answer this).
(Please answer all 3)
- I’m just trying to use the mock bindings to write some unit tests so that I can verify that a function call is creating the correct data buffers that ultimately will be passed into a serial device.
- Right now what happens is that I’m mocking out the serialport binding and my adapter invokes the
write
function. However, I keep trying to listen to an event to see when that happens and I’m not getting one. - What should have happened? I don’t really know – that’s why I’m asking. I’m sure I have done something wrong in the setup. Just hoping for a pointer in the right direction.
Code to Reproduce the Issue
adapter class is an event emitter that accepts a port
module.exports = class Adapter extends events.EventEmitter {
constructor ({ port }) {
super();
this.port = port;
}
doSomething() {
// call stuff and create an object here
const obj = getSomeObjectFromSomewhere();
this.port.write(obj, 'utf8', (err) => {
if (err) {
this.emit('error', err);
}
});
}
}
For now, my mock is really just a constructor calling super
const Adapter = require('../index');
module.exports = class MockAdapter extends Adapter {
constructor({ port }) {
super({ port });
}
// maybe I setup some stuff for unit testing here for my mock
}
now here is my unit test
const chai = require('chai');
const MockAdapter = require('./MockAdapter');
const SerialPort = require('serialport/test');
const MockBinding = SerialPort.Binding;
chai.should();
let port = null;
let adapter = null;
describe('adapter', () => {
beforeEach(() => {
const portPath = 'COM_ANYTHING'
MockBinding.createPort(portPath, { echo: true, record: false });
port = new SerialPort(portPath);
adapter = new MockAdapter({ port });
});
it('should call doSomething() with correct buffer', (done) => {
const buf = Buffer.alloc(64);
// do stuff to manually setup buffer here
// verify that when our adapter writes a value, we get the expected data
port.on('write', (val) => {
val.should.be.an('array').and.have.members(buf.toJSON().data);
done();
});
// call doSomething(), which will force adapter to write a buffer to the serial port
adapter.doSomething();
});
});
Versions, Operating System and Hardware
- SerialPort@7.0.2
- Node.js v: 10.6.0
- OS: Mac
- Hardware and chipset: N/A
Issue Analytics
- State:
- Created 5 years ago
- Comments:6 (3 by maintainers)
@bdmayes I’m happy to hear you’ve figured it out.
You can try using the
ReadyParser
(https://serialport.io/docs/api-parser-ready) to avoid needing the extra if statement.That was it. For some reason, there is no DEBUG output stemming from my actual project, and mocha is simply telling me that the timeout is exceeded. But I was able to add in the if statement to my test and now it works! Basically I just had to:
data
eventsI’m a little confused why mocha gives me a timeout error in my “actual” code but told me the real error (done being called twice) in the sample project I made. Either way I think I’m all set. Thanks for all of your help!