Hi,
How does one set a configuration node values in a unit test?
Thank you
Hi,
How does one set a configuration node values in a unit test?
Thank you
What node are you talking about??
What is your definition of a ‘unit test’?
I have a node:
// 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:
// 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:
// 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
Looking at your node's js file, you do this:
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:
{ 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?
I want to use a config node. The type is "settings"
// 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>
// 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.
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.
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.
[
{ 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:
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.
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!
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.