Last active
August 28, 2016 11:41
-
-
Save patriksvensson/7f02c47d699a9bfff1dcf7018b237272 to your computer and use it in GitHub Desktop.
NSubstitute problem: How do I verify the call to IBuilder.Register(Action<IContainer>)?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class BuilderExtensionsTests | |
{ | |
public class TheRegisterFooMethod | |
{ | |
[Fact] | |
public void Should_Register_Foo_With_Container() | |
{ | |
// Given | |
var builder = Substitute.For<IBuilder>(); | |
// When | |
builder.RegisterFoo(); | |
// Then | |
builder.Received(1).Register(Arg.Is<Action<IContainer>>(container => | |
{ | |
// Not sure how to verify the call to Action<IContainer> here. | |
// This is obviously wrong... | |
container.RegisterType<Foo>(); | |
})); | |
} | |
} | |
} | |
public static class BuilderExtensions | |
{ | |
public static void RegisterFoo(this IBuilder builder) | |
{ | |
builder.Register(container => container.RegisterType<Foo>()); | |
} | |
} | |
public interface IBuilder | |
{ | |
void Register(Action<IContainer> action); | |
} | |
public interface IContainer | |
{ | |
void RegisterType<T>(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
NSubstitute.Exceptions.ReceivedCallsException | |
Expected to receive exactly 1 call matching: | |
Register(Action<IContainer>) | |
Actually received no matching calls. | |
Received 1 non-matching call (non-matching arguments indicated with '*' characters): | |
Register(*Action<IContainer>*) | |
at NSubstitute.Core.ReceivedCallsExceptionThrower.Throw(ICallSpecification callSpecification, IEnumerable`1 matchingCalls, IEnumerable`1 nonMatchingCalls, Quantity requiredQuantity) | |
at NSubstitute.Routing.Handlers.CheckReceivedCallsHandler.Handle(ICall call) | |
at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() | |
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate) | |
at NSubstitute.Routing.Route.Handle(ICall call) | |
at NSubstitute.Proxies.CastleDynamicProxy.CastleForwardingInterceptor.Intercept(IInvocation invocation) | |
at Castle.DynamicProxy.AbstractInvocation.Proceed() | |
at ClassLibrary1.BuilderExtensionsTests.TheRegisterFooMethod.Should_Register_Foo_With_Container() in C:\Source\Local\ClassLibrary1\BuilderExtensionsTests.cs:line 21 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The reason for the test failure is that NSubstitute generally compares arguments by reference, so unless you have a reference to the precise
Action<IContainer>
instance this type of assertion won't work.There are a few ways to approach testing this. I would probably do something like this:
Whenever
builder.Register
is called, NSubstitute will invoke theAction<IContainer>
argument with the given substitute container. We then check that whenbuilder.RegisterFoo()
is called it will be passed an action that willRegisterType<Foo>
on any container it is given. This checks thatbuilder.Register
was called (tested implicitly) with an action that works as expected (tested explicitly).