Ok, there may be some terminology mismatch here - let me see if I can clarify without making things worse.
The overall architecture, as I’m using it:

So I’m using the term “Worker” in the context as described at Worker and Background Tasks — Channels 4.0.0 documentation
The consumers:
- Receive messages from the browser(s),
- Figures out which worker needs to process that message
- Forwards the message to the right worker, via the channel layer
The guts of the work is being done in the workers.
What’s not shown in the diagram is that a worker, in the process of handling a message, could post additional messages to also be processed by the same worker, or by a different worker. So running the worker in this context means that the worker process is listening to 4 channels.
That’s what I’m wanting to test. I need to send a message to worker “A”, and (potentially) wait for responses from workers “A” and “B”.
One final aspect of this is that the logic for worker “A” is really quite trivial.
- Read the message,
- Get some state information from a Model,
- Call a function as identified by the combination of message and state
- Determine the new state,
- Prepare a response by calling a different function
So what I’m really trying to test here is a state machine.
Testing the logic isn’t the issue. These tests are being created to test all the state transitions and verify that the state machine is accurate.
What I have working:

This works, but every time I make a change to the worker, I need to restart it before restarting the tests.
I wouldn’t really call this E2E, because I’m completely bypassing the Consumer layer. But I acknowledge that it’s not truly a “unit test” either because of the dispatch from worker “A” to worker “B”.
In theory, I should test the message to worker “B” separately from the message to worker “A”, and I’m not ruling that out as an option.
Where I’m trying to get to:

Now, if I start a separate thread within a fixture, I can (kinda, sorta, effectively) do this now. The problem is that I’m not cleanly stopping that thread after a test.
What I’d really like to get to:

And that’s where I have some ideas.
Also, in thinking more about it based on what you’ve said, I may try the even more simplified version:

Like I said - I ain’t done yet…