question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How to properly unit test with mock bindings

See original GitHub issue

Summary 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:closed
  • Created 5 years ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
HipsterBrowncommented, Oct 11, 2018

@bdmayes I’m happy to hear you’ve figured it out.

add in the if statement above to throw away the READY event

You can try using the ReadyParser (https://serialport.io/docs/api-parser-ready) to avoid needing the extra if statement.

1reaction
bdmayescommented, Oct 11, 2018

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:

  • change this back to listen for data events
  • add in the if statement above to throw away the READY event

I’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!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Stubbing and Mocking with Mockito and JUnit - Semaphore CI
The best solution for a true unit test is to completely remove the database dependency. We will stub the database connection instead, and...
Read more >
Override Ninject binding locally inside a test method to bind ...
Where Kernel is the object that you used to create the binding. TypeToBind is the type that you want to inject dependency. Mock.Object...
Read more >
Python Mocking: A Guide to Better Unit Tests - Toptal
This comprehensive guide to Python mocking will help you keep your unit tests straightforward and explain how to best use the mock.unittest library...
Read more >
Isolating Dependencies in Tests Using Mocks and Stubs
Enter mocks and stubs. Unit tests check on the behavior of units. Think of a class as being a unit. Classes, more often...
Read more >
Mocking in Unit Tests with Mockito - Spring Framework Guru
When unit testing classes developed for a Spring application, you often need to mock components. Mockito is a very popular solution to use...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found