Yes I created a test project:
TestSubflow
Node B and C are equal in TestFlow and TestSubflow
Flow file:
[
{
"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:
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