Suppose I want to create a custom ISourceBlock<T>
. From the MSDN sliding window example, I could begin the construction of my custom block like so:
public sealed class SomeCustomBlock<T> : ISourceBlock<T>
{
private readonly int _somePrivateMember = 0;
private readonly ISourceBlock<T> _source = new BufferBlock<T>();
public void Complete() => _source.Complete();
public void Fault(Exception exception) => _source.Fault(exception);
public Task Completion => _source.Completion;
public T? ConsumeMessage(DataflowMessageHeader messageHeader, ITargetBlock<T> target, out bool messageConsumed)
{
return _source.ConsumeMessage(messageHeader, target, out messageConsumed);
}
public IDisposable LinkTo(ITargetBlock<T> target, DataflowLinkOptions linkOptions)
{
return _source.LinkTo(target, linkOptions);
}
public void ReleaseReservation(DataflowMessageHeader messageHeader, ITargetBlock<T> target)
{
_source.ReleaseReservation(messageHeader, target);
}
public bool ReserveMessage(DataflowMessageHeader messageHeader, ITargetBlock<T> target)
{
return _source.ReserveMessage(messageHeader, target);
}
}
The trouble is, since the implementation of the ISourceBlock<T>
interface is forwarded to my private _source
field, linked blocks will not call SomeCustomBlock
's implementation of ConsumeMessage
, ReleaseReservation
, and ReserveMessage
methods directly: they'll call the _source
's, aka BufferBlock<T>
's implementation. In fact, I have had a heck of a time trying to get the SomeCustomBlock
's implementation of these methods to be called at all; any target that calls these methods will communicate with _source
since that is the block they directly link with.
My questions:
- How can I write unit tests to verify that I've been a good developer and have not broken
SomeCustomBlock
's implementation of theConsumeMessage
,ReleaseReservation
, andReserveMessage
methods? I work a lot with NUnit, but I'm not opposed to another testing framework if it's required. - Is there a better way to create a custom TPL block that I can more easily test fully, assuming I need to derive directly from
ISourceBlock<T>
rather than using the Encapsulate method?