0

E.g. I have a class with a Process method, in this method I set up a number of things e.g.

public class messageProcessor
{
...
  public string Process(string settings)
  {
    var elementFactory = new ElementFactory();
    var strategyToUse = new legacyStrategy();
    ...
    var resources = new messageResource(
       elementFactory,
       strategyToUse,
       ...);
  }
}

Is it possible for me to create an instance of this class but when I call the Process method, replace (for example) elementFactory to be set to my mocked factory.

Is that possible and how would I do it? Thanks

Blingers
  • 789
  • 1
  • 9
  • 22
  • This code is tightly coupled to implementation concerns that make testing it in isolation difficult. consider inverting control on those dependencies and have them explicitly injected via constructor or method injection. – Nkosi Oct 29 '19 at 12:21

1 Answers1

2

If your code depends on the ElementFactory, you can inject the interface of this class through the constructor of the MessageProcessor class.

This is called "Inversion of control".

So for example you created an interface IElementFactory which you can inject into the class via the constructor like this:

public class messageProcessor
{
    private readonly IElementFactory elementFactory;

    public messageProcessor(IElementFactory elementFactory)
    {
        this.elementFactory = elementFactory;
    }

    public string Process(string settings)
    {
        var strategyToUse = new legacyStrategy();
        ...
        var resources = new messageResource(
           this.elementFactory,
           strategyToUse,
           ...);
    }
}

Now, in your test, you can inject a substitute of the IElementFactory. Like this:

public void Test()
{
    var elementFactory = Substitute.For<IElementFactory>();

    // tell the substitute what it should return when a specific method is called.
    elementFactory.AnyMethod().Returns(something);

    var processor = new messageProcessor(elementFactory);
}

At runtime your application should inject an instance of the IElementFactory into the messageProcessor class. You should do this via "Dependency injection".

L01NL
  • 1,753
  • 1
  • 13
  • 17
  • Thanks L01NL, I was hoping for a solution where I didn't need to amend the existing code but this confirms what I thought, that it isn't possible to do that. Many thanks. – Blingers Oct 29 '19 at 12:39