# Units Testing on a Node

**URL:** https://discourse.nodered.org/t/units-testing-on-a-node/40359
**Category:** Developing Nodes
**Created:** [4 February 2021 09:09 UTC](https://discourse.nodered.org/t/units-testing-on-a-node/40359 "2021-02-04T09:09:30Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![jeevan900929](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/jeevan900929/32/36306_2.png) [@jeevan900929](https://discourse.nodered.org/u/jeevan900929)
#### Post date: [4 February 2021 09:09 UTC](https://discourse.nodered.org/t/units-testing-on-a-node/40359/1 "2021-02-04T09:09:31Z")

</div>

Hi,

How does one set a configuration node values in a unit test?

Thank you

---

<div class="post-metadata">

### Author: ![zenofmud](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/zenofmud/32/316_2.png) [@zenofmud](https://discourse.nodered.org/u/zenofmud)
#### Post date: [4 February 2021 11:47 UTC](https://discourse.nodered.org/t/units-testing-on-a-node/40359/2 "2021-02-04T11:47:22Z")

</div>

What node are you talking about??  
What is your definition of a ‘unit test’?

---

<div class="post-metadata">

### Author: ![jeevan900929](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/jeevan900929/32/36306_2.png) [@jeevan900929](https://discourse.nodered.org/u/jeevan900929)
#### Post date: [4 February 2021 12:56 UTC](https://discourse.nodered.org/t/units-testing-on-a-node/40359/3 "2021-02-04T12:56:20Z")

</div>

I have a node:

```auto
// connect.js

module.exports = function (RED) {
  // Define connect node.
  function ConnectNode (config) {
    // Create node.
    RED.nodes.createNode(this, config)

    // Get values from "settings" configuration node.
    this.settings = RED.nodes.getNode(config.settings)
    ...
  }
  ...
}

```

And it is loaded onto a unit test:

```auto
// connect_spec.js

const helper = require('node-red-node-test-helper')
const ConnectNode = require('../nodes/config/connect')

helper.init(require.resolve('node-red'))

describe('Connect Node', function () {
  beforeEach(function (done) {
    helper.startServer(done)
  })

  afterEach(function (done) {
    helper.unload()
    helper.stopServer(done)
  })

  // This test passes.
  it('should be loaded', function (done) {
    const flow = [{ id: 'n1', type: 'connect', name: 'Connect to EC25', settings: { verbose: 4, simulation: true, serialPort: '', audioDevice: '' } }]
    helper.load(ConnectNode, flow, function () {
      const n1 = helper.getNode('n1')
      n1.should.have.property('name', 'Connect to EC25')
      n1.should.have.property('settings')
      done()
    })
  })

  // This test hangs
  it('should connect', function (done) {
    const flow = [{ id: 'n1', type: 'connect', name: 'Connect to EC25', settings: { verbose: 4, simulation: true, serialPort: '', audioDevice: '' }, wires: [['n2']] },
      { id: 'n2', type: 'helper' }
    ]
    helper.load(ConnectNode, flow, function () {
      const n1 = helper.getNode('n1')
      const n2 = helper.getNode('n2')
      n2.on('input', function (msg) {
        msg.should.have.property('payload', 'hello world!')
        done()
      })
      n1.receive({ payload: "hello world!" })
    })
  })
})

```

The problem I am facing is, that execution hangs when a configuration node's value is read:

```auto
// connect.js

    // Get values from "settings" configuration node.
    this.settings = RED.nodes.getNode(config.settings)
    // Test halts when this.settings is read
    console.log(this.settings.serialPort)

```

It seems like the unit test has to "load" the config node, I do not know how this works in the backend of things. It would be great if there is a way to initialize a configuration node in a unit test. Right now it seems to be reading some uninitialized value which hangs the test.  
  
  
Thanks

---

<div class="post-metadata">

### Author: ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)
#### Post date: [4 February 2021 13:04 UTC](https://discourse.nodered.org/t/units-testing-on-a-node/40359/4 "2021-02-04T13:04:17Z")

</div>

Looking at your node's js file, you do this:

```auto
this.settings = RED.nodes.getNode(config.settings)

```

That implies you expect `config.settings` to be the id of a configuration node.

In you test flow, you are providing a configuration of:

```auto
{ id: 'n1', type: 'connect', name: 'Connect to EC25', settings: { verbose: 4, simulation: true, serialPort: '', audioDevice: '' } }

```

Here, `settings` is not the id of a config node - its an object of key/value pairs.

So the question is more about how you want this to work.

If you want to use a Config node, where have you defined it in the `.js` file? What `type` does it have?

---

<div class="post-metadata">

### Author: ![jeevan900929](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/jeevan900929/32/36306_2.png) [@jeevan900929](https://discourse.nodered.org/u/jeevan900929)
#### Post date: [4 February 2021 13:08 UTC](https://discourse.nodered.org/t/units-testing-on-a-node/40359/5 "2021-02-04T13:08:53Z")

</div>

I want to use a config node. The type is "settings"

```auto
// settings.html

<script type="text/javascript">
    RED.nodes.registerType('settings', {
        category: 'config',
        color: '#8d6b94',
        defaults: {
            verbose: { value: 4, required: true, validate: RED.validators.number() },
            simulation: { value: true, required: true },
            serialPort: { value: "/dev/ttyUSB3", required: true },
            audioDevice: { value: "sysdefault:CARD=EC25", required: true }
        },
        label: function () {
            return this.verbose + ":" + this.simulation + ":" + this.serialPort + ":" + this.audioDevice;
        }
    });
</script>

<script type="text/html" data-template-name="settings">
    <div class="form-row">
        <label for="node-config-input-verbose"><i class="fa fa-bookmark"></i> Verbose Logging</label>
        <select name="node-config-input-verbose" id="node-config-input-verbose">
            <option value="0">NONE</option>
            <option value="1">ERROR</option>
            <option value="2" selected="selected">ERROR, WARNING</option>
            <option value="3">ERROR, WARNING, INFO</option>
            <option value="4">ERROR, WARNING, INFO, DEBUG</option>
        </select>
    </div>
    <div class="form-row">
        <label for="node-config-input-simulation"><i class="fa fa-bookmark"></i> Simulation</label>
        <input type="checkbox" id="node-config-input-simulation">
    </div>
    <div class="form-row">
        <label for="node-config-input-serialPort"><i class="fa fa-bookmark"></i> Serial Port Name</label>
        <input type="text" id="node-config-input-serialPort">
    </div>
    <div class="form-row">
        <label for="node-config-input-audioDevice"><i class="fa fa-bookmark"></i> Audio Device Name</label>
        <input type="text" id="node-config-input-audioDevice">
    </div>
</script>

```

```auto
// settings.js

module.exports = function (RED) {
  function SettingsNode (n) {
    RED.nodes.createNode(this, n)
    this.verbose = n.verbose
    this.simulation = n.simulation
    this.serialPort = n.serialPort
    this.audioDevice = n.audioDevice
  }
  RED.nodes.registerType('settings', SettingsNode)
}

```

I tried adding it to the unit test's flow, but no luck with that.

```auto
const flow = [{ id: 'n1', type: 'connect', name: 'Connect to EC25', settings: "n3", wires: [['n2']] },
      { id: 'n2', type: 'helper' },
      {
        id: 'n3',
        type: 'settings',
        verbose: '4',
        simulation: true,
        serialPort: '/dev/ttyUSB3',
        audioDevice: 'sysdefault:CARD=EG25G'
      }
    ]

```

I do not know if I have to "import" the `SettingsNode` somewhere in the unit test.

---

<div class="post-metadata">

### Author: ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)
#### Post date: [4 February 2021 13:15 UTC](https://discourse.nodered.org/t/units-testing-on-a-node/40359/6 "2021-02-04T13:15:08Z")

</div>

My immediate feedback is don't call it `settings`. Types must be unique - calling your node something as general as that is very likely to cause conflicts. Likewise `connect` is too generic - give them a name that is more related to whatever it is connecting to.

So, with that extra information, you need a test flow that includes both the `connect` node and its `settings` node.

```auto
[
   { id: 'n1', type: 'connect', name: 'Connect to EC25', settings: "my-settings-node", wires: [['n2']] },
   { id: "my-settings-node", verbose: 4, simulation: true, serialPort: '', audioDevice: '' },
   { id: 'n2', type: 'helper' }
 ]

```

You also need to tell the test helper about the config node:

```auto
const ConnectNode = require('../nodes/config/connect')
const SettingsNode = require('../nodes/config/settings')
...
helper.load([ConnectNode, SettingsNode], flow, function () {

```

But as I said at the start - pick more specific node type names.

---

<div class="post-metadata">

### Author: ![jeevan900929](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/jeevan900929/32/36306_2.png) [@jeevan900929](https://discourse.nodered.org/u/jeevan900929)
#### Post date: [4 February 2021 13:17 UTC](https://discourse.nodered.org/t/units-testing-on-a-node/40359/7 "2021-02-04T13:17:29Z")

</div>

> [@knolleary](#):
>
> `helper.load([ConnectNode, SettingsNode]`

I see, this makes a lot of sense. There was no documentation on loading multiple nodes for the helper module. I will give this a try. Thank you!

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)
#### Post date: [18 February 2021 13:18 UTC](https://discourse.nodered.org/t/units-testing-on-a-node/40359/8 "2021-02-18T13:18:23Z")

</div>

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.
