0

I am trying to use NSubstitution in my C# Unit testing program.

I am trying to do a substitution on a method called inside of a mehtod. here is an example:

public class operation
{
  public int addition(int a, int b)
  {
     return (a + b);
  }
} 

public class anotherClass
{
  public int increment(int ax, int bx)
  {
    operation loc = new operation();
    ax = loc.addition(ax,bx);
    return (ax + 1);
  }
}

Is it possible to call increment() method in my main function and apply substitution to the addition() method?

I want to force a return value in the addition() method when called in the increment() method. e.g. force an ecxeption throw.

Also, I can't edit the code so adding an interface implementation would not be a good solution.

Angelo Charl
  • 347
  • 4
  • 15
  • Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. – mybirthname Oct 26 '16 at 13:45
  • I have added more clarity to the objective. @mybirthname – Angelo Charl Oct 26 '16 at 13:51
  • NSubstitute always returns a new object where you can override the methods (provided you're substituting an interface or a class with virtual methods), it doesn't change existing objects or "normal" .NET objects. Since you're constructing a new `operation` inside the method in question, you can't change that new object, you have to first ask NSubstitute to create a substitution-variant of it, then you have to give this to the method and have it use this new object instead of creating its own. – Lasse V. Karlsen Oct 27 '16 at 08:15

2 Answers2

0

Since you're creating a new instance of operation inside the method you're testing (increment), there is no way to get NSubstitut to proxy your call to addition - you're better off (for many reasons, one of which is testability) using Inversion of control to be able to substitute your functionality:

public interface IOperation
{
    int addition(int a, int b);
}

public class operation : IOperation
{
  public int addition(int a, int b)
  {
     return (a + b);
  }
} 

public class anotherClass
{
  private readonly IOperation _operation;
  public anotherClass(IOperation operation)
  {
       _operation = operation;
  }

  public int increment(int ax, int bx)
  {        
    ax = _operation.addition(ax,bx);
    return (ax + 1);
  }
}

That way, you can pass an instance of your operation class to anotherClass when running your application, and pass an NSubstitute.Substitute.For<IOperation>() in your unit tests. You can then use that mock to get it to return whatever you want:

 var mockOperation = NSubstitute.Substitute.For<IOperation>();
 mockOperation.addition(Arg.Any<int>(), Arg.Any<int>()).Return(/*...*/);
Community
  • 1
  • 1
KMoussa
  • 1,568
  • 7
  • 11
  • So in short, if I am unable to change the code(add interface) which I am testing then it is impossible to do it? – Angelo Charl Oct 26 '16 at 14:02
  • @AngeloCharl I can't think of a way to do it without changing the code - if the classes are in different assemblies then you might have a go at stubbing `operation` and referencing it instead of the original assembly, but even that sounds too messy tbh – KMoussa Oct 26 '16 at 14:06
0

To do this you have to pass to anotherClass dependency to operation class. You can do this in different ways, one of them is inject it using constructor, but firstly you have to add IOperation interface to be able to mock it using NSubstitute. Example code could look like:

 public interface Ioperation
        {
            int addition(int a, int b);
        }

        public class operation : Ioperation
        {
            public int addition(int a, int b)
            {
                return (a + b);
            }
        }

        public class anotherClass
        {

            Ioperation _operation;
            public anotherClass(Ioperation operation)
            {
                _operation = operation;
            }

            public int increment(int ax, int bx)
            {
                operation loc = new operation();
                ax = loc.addition(ax, bx);
                return (ax + 1);
            }
        }

Then you can mock it in NSubstitute in following way:

operation.addition(Arg.Any<int>(), Arg.Any<int>()).Throws(new Exception());

and pass it via constructor

luki
  • 72
  • 2