-1

I've created this test:

[TestFixture]
public class UsersTests
{
    private Core.Kernel coreKernel;
    private Core.Configuration.ICoreConfiguration coreConfiguration;

    [SetUp]
    public void SetUp()
    {
        this.coreConfiguration = NSubstitute.Substitute.For<Core.Configuration.ICoreConfiguration>();
        this.coreKernel = NSubstitute.Substitute.For<Core.Kernel>(this.coreConfiguration);

        this.coreKernel.Initialize();
    }

    [Test]
    public void AddUserTest()
    {
        Core.Communication.Entities.UserIdentity receivedUserIdentity = new Core.Communication.Entities.UserIdentity("user1", "passwd1");

        ((Core.Communication.ICoreService)this.coreKernel).AddUserIdentity(receivedUserIdentity);
        this.coreKernel.Received(100).AddUser(Arg.Is<Core.Identity.UserIdentity>(u => u.UserId.Equals(receivedUserIdentity.UserId)));
    }
}

where Core.Kernel is:

public partial class Kernel : Core.IKernel
{
    public Kernel(Configuration.ICoreConfiguration configuration)
            : this(configuration, null, Enumerable.Empty<Type>())
    {

    }

    public Kernel(Configuration.ICoreConfiguration configuration, Communication.ICoreService service, IEnumerable<Type> producerTypes)
    {
        if (configuration == null)
            throw new ArgumentException("configuration object must be provided", "configuration");

        if (producerTypes.Any(t => !t.IsAssignableFrom(typeof(Core.Extensibility.AbstractProducerPlugin))))
            throw new ArgumentException("All types must inherit from AbstractProducerPlugin", "plugins");


        this.state = KernelState.initializing;

        this.configuration = configuration;
        this.service = service ?? this;
        this.producerTypes = producerTypes;

        this.backends = new Dictionary<Core.Identity.DomainIdentity, Backend.Infrastructure.IBackend>();
    }

    internal virtual void AddUser(Core.Identity.UserIdentity userIdentity) {...}
}

Nevertheless, this.coreKernel.Received(100).AddUser(... is not called 100 times, only one. What am I doing wrong?

I mean, I'm not trying to make 100 calls to AddUser. I'm checking AddUser should be called 100 times. So, assertion should fail.

EDIT

Guess this code (Core.IKernel.AddUserIdentity(...) implementation):

public class Core.Kernel {
    public override void Core.IKernel.AddUserIdentity(UserIdentity userIdentity) {
        this.AddUser(userIdentity); <<----- AddUser(...) is called
    }
}

I think the problem is related with:

  1. Core.Kernel implements Core.IKernel. Core.IKernel has AddUserIdentity(...) method.
  2. I'm mocking Core.Kernel instead of mocking a Core.IKernel.
  3. According to Core.IKernel.AddUserIdentity(...) method implementation AddUser should ne reached.
  4. AddUser is an internal virtual method of Core.Kernel. It's not an implementation of any method interface.

I want to assert AddUser is called once when AddUserIdentity is reached.

Other questions about mocking:

  1. For<T> where T is a concrete class -> virtual methods are replaced? no virtual methods are executed?
  2. ForPartsOf<T> where T is a concrete class -> Which parts of this class are mocked (virtual methods, overrided interface methods)?
Jordi
  • 20,868
  • 39
  • 149
  • 333
  • I can't tell from this code why the assertion is not failing, but thought I should mention you appear to be substituting for `Core.Kernel` but want to test some of the logic in it. For example, you are calling `coreKernel.Initialise()` and `AddUserIdentity(...)` on the substitute, which will not run any actual logic if it is `virtual`. You may want to check the documentation on [partial substitutes](http://nsubstitute.github.io/help/partial-subs/) to achieve this. Or better yet, refactor the design to allow you to new up a real `Core.Kernel` and test its interactions with its dependencies. – David Tchepak Feb 14 '17 at 23:51
  • Thanks David for your comments. Could you take a look on post? I've edited it in order to add some details. – Jordi Feb 15 '17 at 07:36

1 Answers1

0

It is only called once because you are only calling AddUser once. The Received assertion checks how many times it has been called, it doesn't tell NSubstitue to call your method 100 times, you need to do that manually :)

NSubstitute also gives you the option of asserting a specific number of calls were received by passing an integer to Received(). This will throw if the substitute does not receive exactly that many matching calls

http://nsubstitute.github.io/help/received-calls/

user9993
  • 5,833
  • 11
  • 56
  • 117
  • Thanks user9993 for your comment. I understand what's the code do, nevertheless, the assertion should fail, nevertheless it success. `AddUser` should be called once after having executed `AddUserIdentity`. – Jordi Feb 14 '17 at 08:54