Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Received Calls doesn't work #284

Closed
jeusdi opened this issue Feb 14, 2017 · 3 comments
Closed

Received Calls doesn't work #284

jeusdi opened this issue Feb 14, 2017 · 3 comments

Comments

@jeusdi
Copy link

jeusdi commented Feb 14, 2017

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) {...}
}

And Core.IKernel is:

public interface IKernel
{

    Core.Configuration.ICoreConfiguration Configuration { get; }
    Core.Communication.ICoreService CoreService { get; }
    IEnumerable<Type> ProducerTypes { get; }

    IEnumerable<Core.Identity.UserIdentity> UserIdentities { get; }

    void Initialize();

    IEnumerable<string> GetPluginChannels(Core.Identity.UserIdentity userIdentity);
    IEnumerable<Core.Extensions.PluginInfo> GetPlugins(Core.Identity.UserIdentity userIdentity);
    IEnumerable<string> GetPluginChannels(Core.Identity.UserIdentity userIdentity, string pluginId);
}

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.

@dtchepak
Copy link
Member

Hi @jeusdi,

I left a comment on your SO question. Summary: I need more information to work out why this is passing incorrectly, but before we work that out we should sort out the problem of mocking the class you are testing.

Is it possible for you to strip the example down to something I can run locally? If you can reproduce the problem in a test that you can post in its entirety I think that will be our best bet of sorting out what is happening.

In case it helps in the meantime, you can use the ReceivedCalls() extension method (coreKernel.ReceivedCalls()) to get a list of all calls received by coreKernel and see how it differs from what you expect.

Regards,
David

@jeusdi
Copy link
Author

jeusdi commented Feb 16, 2017

Hi @dtchepak. Thanks for your comments.

Currently, I'm using NSubstituteMockingKernel in order to get my Core.Kernel:

[TestFixture]
public class UsersManagementTests
{
private readonly NSubstituteMockingKernel IoCKernel;

    public UsersManagementTests()
    {
        this.IoCKernel = new NSubstituteMockingKernel();
    }

    [SetUp]
    public void SetUp()
    {
        this.IoCKernel.Reset();
    }

    [Test(Description = "Configured Users are well loaded on Kernel")]
    public void AddUserFromConfigurationTest()
    {
        //Setup Data
        Core.Configuration.UserIdentity userConfiguration = Core.Configuration.UserIdentity.Create("u1", "p1");
        IEnumerable<Core.Configuration.UserIdentity> configurationUsers = new List<Core.Configuration.UserIdentity>() { userConfiguration };

        //Setup Mocks
        this.IoCKernel.Get<Core.Configuration.ICoreConfiguration>().UserIdentities.Returns(configurationUsers);

        Core.Kernel kernel = (Core.Kernel)this.IoCKernel.Get<Core.Kernel>();
        kernel.Received(1).AddUser(Arg.Any<Core.Identity.UserIdentity>()); <<<<<< exception

        kernel.UserIdentities
            .Should()
                .NotBeEmpty()
                .And.HaveCount(1)
                .And.OnlyContain(u => u.UserId.Equals(userConfiguration.UserId) && u.Password.Equals(userConfiguration.Password));
    }
}

So, I'm getting a Core.Kernel substitution on this.IoCKernel.Get<Core.Kernel>();. injection. At the same time the prevously configured mock Core.Configuration.ICoreConfiguration is injected on Core.Kernel since it has a constructor like: constructor(ICoreConfiguretion configuration). Everything compiles, nevertheless, when I'm trying to test the mocked Core.Kernel object, I'm getting a NSubstitute.Exceptions.NotASubstituteException exception message now on last line:

NSubstitute extension methods like .Received() can only be called on objects created using Substitute.For() and related methods.

As you can see I'm trying to test AddUser method is called once at least. AddUser must be called according my Core.Kernel implementation.

@dtchepak
Copy link
Member

I'm not familiar with NSubstituteMockingKernel sorry. Maybe try getting the test working without that first, then add it back in once the basics of the test are working?

         //Setup Data
        var userConfiguration = Core.Configuration.UserIdentity.Create("u1", "p1");
        var configurationUsers = new List<Core.Configuration.UserIdentity>() { userConfiguration };

        //Setup Mocks
        var coreConfig = Substitute.For<Core.Configuration.ICoreConfiguration>();
        coreConfig.UserIdentities.Returns(configurationUsers);

        // Act
        var kernel = new Core.Kernel(coreConfig);

       // Assert
       ....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants