{"action":"created","issue":{"url":"https://api.github.com/repos/node-serialport/node-serialport/issues/1698","repository_url":"https://api.github.com/repos/node-serialport/node-serialport","labels_url":"https://api.github.com/repos/node-serialport/node-serialport/issues/1698/labels{/name}","comments_url":"https://api.github.com/repos/node-serialport/node-serialport/issues/1698/comments","events_url":"https://api.github.com/repos/node-serialport/node-serialport/issues/1698/events","html_url":"https://github.com/node-serialport/node-serialport/issues/1698","id":369238039,"node_id":"MDU6SXNzdWUzNjkyMzgwMzk=","number":1698,"title":"How to properly unit test with mock bindings","user":{"login":"bdmayes","id":5610870,"node_id":"MDQ6VXNlcjU2MTA4NzA=","avatar_url":"https://avatars2.githubusercontent.com/u/5610870?v=4","gravatar_id":"","url":"https://api.github.com/users/bdmayes","html_url":"https://github.com/bdmayes","followers_url":"https://api.github.com/users/bdmayes/followers","following_url":"https://api.github.com/users/bdmayes/following{/other_user}","gists_url":"https://api.github.com/users/bdmayes/gists{/gist_id}","starred_url":"https://api.github.com/users/bdmayes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bdmayes/subscriptions","organizations_url":"https://api.github.com/users/bdmayes/orgs","repos_url":"https://api.github.com/users/bdmayes/repos","events_url":"https://api.github.com/users/bdmayes/events{/privacy}","received_events_url":"https://api.github.com/users/bdmayes/received_events","type":"User","site_admin":false},"labels":[{"id":46026455,"node_id":"MDU6TGFiZWw0NjAyNjQ1NQ==","url":"https://api.github.com/repos/node-serialport/node-serialport/labels/support","name":"support","color":"fbca04","default":false}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":5,"created_at":"2018-10-11T17:59:07Z","updated_at":"2018-10-11T19:30:05Z","closed_at":"2018-10-11T19:26:33Z","author_association":"NONE","body":"### Summary of Problem\r\nI'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).\r\n\r\nI 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).\r\n\r\n(Please answer all 3)\r\n\r\n- 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.\r\n- 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.\r\n- 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.\r\n\r\n### Code to Reproduce the Issue\r\n\r\n#### adapter class is an event emitter that accepts a port\r\n```js\r\nmodule.exports = class Adapter extends events.EventEmitter {\r\n  constructor ({ port }) {\r\n    super();\r\n    this.port = port;\r\n  }\r\n\r\n  doSomething() {\r\n    // call stuff and create an object here\r\n    const obj = getSomeObjectFromSomewhere();\r\n    this.port.write(obj, 'utf8', (err) => {\r\n      if (err) {\r\n        this.emit('error', err);\r\n      }\r\n    });\r\n  }\r\n}\r\n```\r\n\r\n#### For now, my mock is really just a constructor calling super\r\n```js\r\nconst Adapter = require('../index');\r\n\r\nmodule.exports = class MockAdapter extends Adapter {\r\n  constructor({ port }) {\r\n    super({ port });\r\n  }\r\n\r\n  // maybe I setup some stuff for unit testing here for my mock\r\n}\r\n```\r\n\r\n#### now here is my unit test\r\n```js\r\nconst chai = require('chai');\r\nconst MockAdapter = require('./MockAdapter');\r\nconst SerialPort = require('serialport/test');\r\n\r\nconst MockBinding = SerialPort.Binding;\r\nchai.should();\r\n\r\nlet port = null;\r\nlet adapter = null;\r\n\r\ndescribe('adapter', () => {\r\n  beforeEach(() => {\r\n    const portPath = 'COM_ANYTHING'\r\n    MockBinding.createPort(portPath, { echo: true, record: false });\r\n    port = new SerialPort(portPath);\r\n\r\n    adapter = new MockAdapter({ port });\r\n  });\r\n\r\n  it('should call doSomething() with correct buffer', (done) => {\r\n    const buf = Buffer.alloc(64);\r\n    // do stuff to manually setup buffer here\r\n\r\n    // verify that when our adapter writes a value, we get the expected data\r\n    port.on('write', (val) => {\r\n      val.should.be.an('array').and.have.members(buf.toJSON().data);\r\n      done();\r\n    });\r\n\r\n    // call doSomething(), which will force adapter to write a buffer to the serial port\r\n    adapter.doSomething();\r\n  });\r\n});\r\n```\r\n\r\n### Versions, Operating System and Hardware\r\n\r\n- SerialPort@7.0.2\r\n- Node.js v: 10.6.0\r\n- OS: Mac\r\n- Hardware and chipset: N/A\r\n"},"comment":{"url":"https://api.github.com/repos/node-serialport/node-serialport/issues/comments/429088379","html_url":"https://github.com/node-serialport/node-serialport/issues/1698#issuecomment-429088379","issue_url":"https://api.github.com/repos/node-serialport/node-serialport/issues/1698","id":429088379,"node_id":"MDEyOklzc3VlQ29tbWVudDQyOTA4ODM3OQ==","user":{"login":"HipsterBrown","id":3051193,"node_id":"MDQ6VXNlcjMwNTExOTM=","avatar_url":"https://avatars3.githubusercontent.com/u/3051193?v=4","gravatar_id":"","url":"https://api.github.com/users/HipsterBrown","html_url":"https://github.com/HipsterBrown","followers_url":"https://api.github.com/users/HipsterBrown/followers","following_url":"https://api.github.com/users/HipsterBrown/following{/other_user}","gists_url":"https://api.github.com/users/HipsterBrown/gists{/gist_id}","starred_url":"https://api.github.com/users/HipsterBrown/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/HipsterBrown/subscriptions","organizations_url":"https://api.github.com/users/HipsterBrown/orgs","repos_url":"https://api.github.com/users/HipsterBrown/repos","events_url":"https://api.github.com/users/HipsterBrown/events{/privacy}","received_events_url":"https://api.github.com/users/HipsterBrown/received_events","type":"User","site_admin":false},"created_at":"2018-10-11T19:30:05Z","updated_at":"2018-10-11T19:30:05Z","author_association":"CONTRIBUTOR","body":"@bdmayes I'm happy to hear you've figured it out. \r\n\r\n> add in the if statement above to throw away the READY event\r\n\r\nYou can try using the `ReadyParser` (https://serialport.io/docs/api-parser-ready) to avoid needing the extra if statement. "}}
{"actor":{"display_login":"HipsterBrown"}}