NIOAsyncTestingChannel

A Channel with fine-grained control for testing.

AsyncTestingChannel.swift:87
iOS
13.0+
macOS
10.15+
tvOS
13.0+
watchOS
6.0+
final class NIOAsyncTestingChannel

NIOAsyncTestingChannel is a Channel implementation that does no actual IO but that does have proper eventing mechanism, albeit one that users can control. The prime use-case for NIOAsyncTestingChannel is in unit tests when you want to feed the inbound events and check the outbound events manually.

Please remember to call finish when you are no longer using this NIOAsyncTestingChannel.

To feed events through an NIOAsyncTestingChannel’s ChannelPipeline use writeInbound(_:) which accepts data of any type. It will then forward that data through the ChannelPipeline and the subsequent ChannelInboundHandler will receive it through the usual channelRead event. The user is responsible for making sure the first ChannelInboundHandler expects data of that type.

Unlike in a regular ChannelPipeline, it is expected that the test code will act as the “network layer”, using readOutbound(as:) to observe the data that the Channel has “written” to the network, and using writeInbound(_:) to simulate receiving data from the network. There are also facilities to make it a bit easier to handle the logic for write and flush (using writeOutbound(_:)), and to extract data that passed the whole way along the channel in channelRead (using readOutbound(as:). Below is a diagram showing the layout of a ChannelPipeline inside a NIOAsyncTestingChannel, including the functions that can be used to inject and extract data at each end.


           Extract data                         Inject data
        using readInbound()                using writeOutbound()
                                                    |
 +---------------+-----------------------------------+---------------+
 |               |           ChannelPipeline         |               |
 |               |                TAIL                              |
 |    +---------------------+            +-----------+----------+    |
 |    | Inbound Handler  N  |            | Outbound Handler  1  |    |
 |    +----------+----------+            +-----------+----------+    |
 |                                                  |               |
 |               |                                                  |
 |    +----------+----------+            +-----------+----------+    |
 |    | Inbound Handler N-1 |            | Outbound Handler  2  |    |
 |    +----------+----------+            +-----------+----------+    |
 |                                                  .               |
 |               .                                   .               |
 | ChannelHandlerContext.fireIN_EVT() ChannelHandlerContext.OUT_EVT()|
 |        [ method call]                       [method call]         |
 |               .                                   .               |
 |               .                                                  |
 |    +----------+----------+            +-----------+----------+    |
 |    | Inbound Handler  2  |            | Outbound Handler M-1 |    |
 |    +----------+----------+            +-----------+----------+    |
 |                                                  |               |
 |               |                                                  |
 |    +----------+----------+            +-----------+----------+    |
 |    | Inbound Handler  1  |            | Outbound Handler  M  |    |
 |    +----------+----------+            +-----------+----------+    |
 |                             HEAD                 |               |
 +---------------+-----------------------------------+---------------+
                 |                                   
            Inject data                         Extract data
        using writeInbound()                using readOutbound()