1

I'm trying to figure out how to test my Ninject library. I mean, my library uses an Ninject kernel in order to resolve all their dependencies. This is the main class of my library:

public class Core : ICore {

    private Ninject.IKernel compositionRoot;

    public Core()
    {
        this.state = KernelState.initializing;
        this.backends = new Dictionary<Core.Identity.DomainIdentity, Backend.Infrastructure.IBackend>();

        this.BuildIoC(compositionRoot);

        this.configuration = this.compositionRoot.Get<Core.Configuration.ICoreConfiguration>();
        this.serviceHost = this.compositionRoot.Get<System.ServiceModel.ServiceHost>();
    }

where BuildIoC() is:

    internal void BuildIoC(Ninject.IKernel compositionRoot = null)
    {
        this.compositionRoot = compositionRoot ?? new Ninject.StandardKernel(
          new IoC.Modules.BackendModule(),
          new IoC.Modules.PluginsModule(),
          new IoC.Modules.ConfigurationModule(),
          new IoC.Modules.ServiceModule(this));
    }

Currently, I need to build some tests on this class. So:

  1. I'd like to "mock" configuration and serviceHost fields. How could I get this?
  2. What does NSubstituteMockingKernel stand exactly for? I don't quite figure out what's that for.

Up to now, I've not been able to achieve anything elegant. I don't know what mock, ninject kernel, modules, classes?

For example, serviceHost is an implementation of a webservice. I'd like Core class loads a mocked configuration object... How would I proceed in order to get this?

A library should use an IoC framework?

Rodia
  • 1,407
  • 8
  • 22
  • 29
Jordi
  • 20,868
  • 39
  • 149
  • 333
  • This may help http://stackoverflow.com/questions/18545983/ninject-auto-mocking-using-nsubstitute – Alexandr Nikitin Feb 13 '17 at 15:17
  • Thanks Alexandr. I already read a bit before. Nevertheless, I don't quite figure out what does NSubstituteMockingKernel solve? – Jordi Feb 13 '17 at 15:39
  • That one is from the library called Ninject.MockingKernel. You can find some docs on github https://github.com/ninject/Ninject.MockingKernel/wiki – Alexandr Nikitin Feb 13 '17 at 16:42
  • What's the difference between using an `StandartKernel` instead of a `MockingKernel` in tests? What amn't able or is better to use `MockingKernel`? – Jordi Feb 14 '17 at 07:23
  • `StandartKernel` is the kernel you use in production. It resolves only registered services. `MockingKernel` was meant to be used in tests. It can resolve services as mocks. Take a look at the documentation and examples please. – Alexandr Nikitin Feb 14 '17 at 11:38
  • I don't quite figure out what means _it can be resolve mocks_ I don't understand why it provides this functionality. I know what mocks stands for, nevertheless, I don't get the need of resolving them into testing environtment using `MockingKernel`. I don't know if I'm explaining so well. – Jordi Feb 14 '17 at 11:59
  • I mean, which is the difference between using `Substitute.For` and `MockingKernel instance; instance.Get()`, which is the added value? – Jordi Feb 14 '17 at 12:07
  • Say you have a class `MyFoo` that you want to test. It has a dependency on `IBar` injected via constructor. The straightforward way is to create a mock for dependency, then create an instance of the sut class using the mock. `MockingKernel` simplifies that process and creates mocks for dependencies automatically when you resolve your class. If you have a dozen of dependencies it makes sense. – Alexandr Nikitin Feb 14 '17 at 12:24
  • Mmm, but what about modules? Is it able to resolve dependencies without setting modules on `MockingKernel` instance? – Jordi Feb 14 '17 at 12:30
  • A module is a class that can be used to bundle up a set of related components to simplify configuration. That's it. You don't need a module to unit test a class. – Alexandr Nikitin Feb 14 '17 at 13:46
  • This is the magic I keep failing figure out! I've been able to get that all dependencies will be mocks, nevertheless, how can I substitute methods amd so on...? – Jordi Feb 14 '17 at 15:00
  • Have you looked at the examples in the links above? – Alexandr Nikitin Feb 14 '17 at 18:32
  • Possible duplicate of [Ninject: auto mocking using NSubstitute?](http://stackoverflow.com/questions/18545983/ninject-auto-mocking-using-nsubstitute) – Alexandr Nikitin Feb 15 '17 at 08:32
  • I've been playing a bit. I need `MockingKernel` injects a mocked object on a constructor of a class. Nevertheless, I need this injected objects `Returns` some values when a property of this is accessed. How can I set `MockingKernel` resolves to an mocked object and setup a behavior for it? – Jordi Feb 15 '17 at 14:26
  • I see you are struggling with it. This isn't the only problem that you faced and will face. I see you created a lot of questions already. I kindly suggest you to read and start from the basics: Regarding this question they are Unit testing, DI principle, IoC containers and how they work. – Alexandr Nikitin Feb 15 '17 at 14:50
  • Ohhh, I've changed tools in order to use `Moq` instead of `NSubstitute`. Could you get me some help about [this question](http://stackoverflow.com/questions/42253692/setup-a-mocked-injected-object-with-moq)? – Jordi Feb 15 '17 at 15:38
  • This is one mother of a class because it has a bunch of modules. Nevertheless, if you don't create any environment connections during initialization - just do a `var core = new Core(); Assert.IsInstaceOf(core.Configuration, typeof(whateverImplementsConfiguration))`, and that is your constructor test. Then for any functional tests; use `var core = (Core)FormatterServices.GetUninitializedObject(typeof(Core)); typeof(Core).GetField("compositionRoot", BindingFlags.Instance | BindingFlags.NonPublic).SerValue(// Sub or Mock here, core); and call methods on core`. – zaitsman Mar 05 '17 at 09:13

1 Answers1

0

I'm fairly new to Unit Testing, but these are my favourite libraries for mocking and IoC. What I have done in the past and worked for me (and I'm not saying it's the best way) was to let NInject instance the dependencies at runtime, that the system needs to consume. But for the tests, I manually create the instances using NSubstitute and I inject them through the constructors (NInject not involved). It can be time consuming sometimes to get the "Arrange" part (from the AAA pattern). Probably there must be a better way, but this worked for me. Hope this helps.

Gonzalo Méndez
  • 548
  • 7
  • 18