# Using Subflows within Node-RED unit tests (node-red-node-test-helper) does NOT work

**URL:** <https://discourse.nodered.org/t/using-subflows-within-node-red-unit-tests-node-red-node-test-helper-does-not-work/59081>\
**Category:** General\
**Created:** [27 February 2022 20:56 UTC](https://discourse.nodered.org/t/using-subflows-within-node-red-unit-tests-node-red-node-test-helper-does-not-work/59081 "2022-02-27T20:56:52Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![BeginnerNode](https://avatars.discourse-cdn.com/v4/letter/b/9e8a1a/32.png) [@BeginnerNode](https://discourse.nodered.org/u/BeginnerNode)\
**Post date:** [27 February 2022 20:56 UTC](https://discourse.nodered.org/t/using-subflows-within-node-red-unit-tests-node-red-node-test-helper-does-not-work/59081/1 "2022-02-27T20:56:52Z")

</div>

Hello together,

I have created several unit tests using node-red-node-test-helper to have end-to-end tests of my flow containg 4 nodes:  
A input  
B function  
C function  
D output

Test worked without any problems for the whole chain sending input values and validate message on output node.

I created a subflow "SUB" containing the function nodes B and C.  
So the main flow is  
A - SUB - D

My expection was that unit test should still work.  
But they do not.

Is there a trick how flows containing subflows can be tested?

BTW flow is still working in Node-RED, just test is no longer working

Thanks in advance

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [27 February 2022 22:01 UTC](https://discourse.nodered.org/t/using-subflows-within-node-red-unit-tests-node-red-node-test-helper-does-not-work/59081/2 "2022-02-27T22:01:27Z")

</div>

> [@BeginnerNode](#):
>
> junit

Junit is for Java. How are you doing the flow tests?

Can you share more detail or a repo?

---

<div class="post-metadata">

**Author:** ![BeginnerNode](https://avatars.discourse-cdn.com/v4/letter/b/9e8a1a/32.png) [@BeginnerNode](https://discourse.nodered.org/u/BeginnerNode)\
**Post date:** [28 February 2022 07:45 UTC](https://discourse.nodered.org/t/using-subflows-within-node-red-unit-tests-node-red-node-test-helper-does-not-work/59081/3 "2022-02-28T07:45:43Z")

</div>

ups yeah sure...unit test 🙂

```auto
const requiredNodes = [
		require("../node_modules/@node-red/nodes/core/function/15-change.js"),
		require("../node_modules/@node-red/nodes/core/common/20-inject.js"),
		require("../node_modules/@node-red/nodes/core/common/21-debug.js"),
		require("../node_modules/@node-red/nodes/core/function/10-function.js"),
		require("../node_modules/@node-red/nodes/core/function/10-switch.js"),
		require("../node_modules/@node-red/nodes/core/function/89-delay.js"),
		require("../node_modules/@node-red/nodes/core/network/10-mqtt.js")
	]

const flow: any[] = require("../flows.json")

it('Verify test flow', function (done) {
	helper.load(requiredNodes, flow, function () {

		// given is flow input
		var inputNode = helper.getNode('A')
		expect('Input Node Name').to.equal(inputNode.name)
		
		// and flow output
		var outputNode = helper.getNode('D')
		expect('Output Node Name').to.equal(outputNode.name)

		// when payload is sent
		inputNode.wires[0].forEach((wire: string) => {
			const node = helper.getNode(wire)
			node.receive(
				{
					payload: false
				}
			)
		})

		// then output message must be created
		outputNode.on("input", (msg: any) => {
			try {
				expect(false).to.equal(msg.payload)
				done()
			} catch (e) {
				done(e)
			}
		})
	})
})

```

To stay on the origin example  
I have an input node A and an output node D  
expected is that when input node A sends payload false output node D should receive payload false.

When in my flow configuration B and C are function nodes everything works as expected.

But as soon as I move the nodes B and C to a subflow, no value is received on D.

Do I have to load the subflow or do i need to do anything else?

Does somebody have an example test with an subflow in the middle of a flow?

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [28 February 2022 07:48 UTC](https://discourse.nodered.org/t/using-subflows-within-node-red-unit-tests-node-red-node-test-helper-does-not-work/59081/4 "2022-02-28T07:48:55Z")

</div>

> [@BeginnerNode](#):
>
> `const flow: any[] = require("../flows.json")`

Are you able to provide the flow.json content?

---

<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:** [28 February 2022 07:52 UTC](https://discourse.nodered.org/t/using-subflows-within-node-red-unit-tests-node-red-node-test-helper-does-not-work/59081/5 "2022-02-28T07:52:14Z")

</div>

I wrote test-helper for unit testing individual nodes. I'm not sure I've ever seen it used to test subflows. So I simply can't say if I'd expect that to work or not.

---

<div class="post-metadata">

**Author:** ![BeginnerNode](https://avatars.discourse-cdn.com/v4/letter/b/9e8a1a/32.png) [@BeginnerNode](https://discourse.nodered.org/u/BeginnerNode)\
**Post date:** [28 February 2022 09:31 UTC](https://discourse.nodered.org/t/using-subflows-within-node-red-unit-tests-node-red-node-test-helper-does-not-work/59081/6 "2022-02-28T09:31:58Z")

</div>

Yes I created a test project:

 ![Tesflow](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/e/2/e24bd1b8bdd8126032e41164c2cc076a1d3b8a0b.png)

TestSubflow

 ![TestSubflow](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/d/b/db5d450adcf7b4b7b1ffe6f83597e8a946291713.png)

Node B and C are equal in TestFlow and TestSubflow

Flow file:

```auto
[
    {
        "id": "0cc4be7a8aa4d1d2",
        "type": "tab",
        "label": "Test Flow",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "842d78cb52b06cf4",
        "type": "subflow",
        "name": "TestSubflow",
        "info": "",
        "category": "",
        "in": [
            {
                "x": 160,
                "y": 100,
                "wires": [
                    {
                        "id": "c6d4d64122fe4930"
                    }
                ]
            }
        ],
        "out": [
            {
                "x": 1020,
                "y": 100,
                "wires": [
                    {
                        "id": "48ba4b4257418165",
                        "port": 0
                    }
                ]
            }
        ],
        "env": [],
        "meta": {},
        "color": "#DDAA99"
    },
    {
        "id": "c6d4d64122fe4930",
        "type": "function",
        "z": "842d78cb52b06cf4",
        "name": "B",
        "func": "msg.payload = !msg.payload\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 430,
        "y": 100,
        "wires": [
            [
                "48ba4b4257418165"
            ]
        ]
    },
    {
        "id": "48ba4b4257418165",
        "type": "function",
        "z": "842d78cb52b06cf4",
        "name": "C",
        "func": "msg.payload = !msg.payload\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 770,
        "y": 100,
        "wires": [
            []
        ]
    },
    {
        "id": "c7cb8f9cd5294ade",
        "type": "inject",
        "z": "0cc4be7a8aa4d1d2",
        "name": "Input",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "false",
        "payloadType": "bool",
        "x": 190,
        "y": 120,
        "wires": [
            [
                "c3ba6884ecee7685"
            ]
        ]
    },
    {
        "id": "a0021e7915c9c92e",
        "type": "function",
        "z": "0cc4be7a8aa4d1d2",
        "name": "B",
        "func": "msg.payload = !msg.payload\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 450,
        "y": 120,
        "wires": [
            [
                "465abef1163f8028"
            ]
        ]
    },
    {
        "id": "465abef1163f8028",
        "type": "function",
        "z": "0cc4be7a8aa4d1d2",
        "name": "C",
        "func": "msg.payload = !msg.payload\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 790,
        "y": 120,
        "wires": [
            [
                "a4ce7070377a10c1"
            ]
        ]
    },
    {
        "id": "a4ce7070377a10c1",
        "type": "debug",
        "z": "0cc4be7a8aa4d1d2",
        "name": "Output",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1190,
        "y": 120,
        "wires": []
    },
    {
        "id": "c3ba6884ecee7685",
        "type": "subflow:842d78cb52b06cf4",
        "z": "0cc4be7a8aa4d1d2",
        "name": "",
        "x": 630,
        "y": 220,
        "wires": [
            [
                "a4ce7070377a10c1"
            ]
        ]
    }
]

```

Unit test:

```auto
import "mocha"
import { expect } from "chai"
import * as sinon from "sinon"
var should = require("should")

describe("my flowtest", () => {

	const helper = require("node-red-node-test-helper")
	
	const requiredNodes = [
		require("../node_modules/@node-red/nodes/core/function/15-change.js"),
		require("../node_modules/@node-red/nodes/core/common/20-inject.js"),
		require("../node_modules/@node-red/nodes/core/common/21-debug.js"),
		require("../node_modules/@node-red/nodes/core/function/10-function.js"),
		require("../node_modules/@node-red/nodes/core/function/10-switch.js"),
		require("../node_modules/@node-red/nodes/core/function/89-delay.js"),
		require("../node_modules/@node-red/nodes/core/network/10-mqtt.js"),
		//require("../node_modules/@node-red/runtime/lib/flows/Subflow.js")
	]

	const loadFlowFile = () => {
		const TYPE_IGNORE_LIST: string[] = ['change', 'function', 'switch', 'delay','subflow']
		const flow: any[] = require("../flow.json")

		// convert unknown types to helper
		flow.forEach((node) => {
			if (!TYPE_IGNORE_LIST.some(e => e === node.type)) {
				node.type = "helper"
			}
		})
		return flow
	}

	const flow: any[] = require("../flow.json")

	before(() => { helper.init(require.resolve('node-red'))})

	beforeEach((done) => { helper.startServer(done)	})

	afterEach(function (done) {
		try {
			helper.unload()
		} catch (err) {
		}
		helper.stopServer(done)
	})

	it('subflow test', function (done) {
		this.timeout(1000)
		
		helper.load(requiredNodes, loadFlowFile(), function () {
			try {
				// given is flow input
				var inputNode = helper.getNode('c7cb8f9cd5294ade')
				expect('Input').to.equal(inputNode.name)

				// and output
				var outputNode = helper.getNode('a4ce7070377a10c1')
				expect('Output').to.equal(outputNode.name)

				// when payload is sent
				inputNode.wires[0].forEach((wire: string) => {
					const node = helper.getNode(wire)
					node.receive({ payload: false })
				})

				// then message must be receivedwith payload false
				outputNode.on("input", (msg: any) => {
					try {
						expect(false).to.equal(msg.payload)
						done()
					} catch (e) {
						done(e)
					}
				})
			} catch (e) {
				done(e)
			}
		})
	})

})

```

If you change the wire from subflow (c3ba6884ecee7685) to node B (a0021e7915c9c92e) of the inject node, then unit testis working.  
But with using subflow it is not working.

I think the problem is that subflow is not correctly registered as requiredNodes.

Hopefully this information helpsfor some support

---

<div class="post-metadata">

**Author:** ![BeginnerNode](https://avatars.discourse-cdn.com/v4/letter/b/9e8a1a/32.png) [@BeginnerNode](https://discourse.nodered.org/u/BeginnerNode)\
**Post date:** [15 March 2022 14:19 UTC](https://discourse.nodered.org/t/using-subflows-within-node-red-unit-tests-node-red-node-test-helper-does-not-work/59081/7 "2022-03-15T14:19:42Z")

</div>

ok thanks for your answer.

How do you usually create integration tests to verify whole flows ?

---

<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:** [14 May 2022 14:20 UTC](https://discourse.nodered.org/t/using-subflows-within-node-red-unit-tests-node-red-node-test-helper-does-not-work/59081/8 "2022-05-14T14:20:30Z")

</div>

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