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, andReserveMessagemethods? 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?