aaronjbaptiste aaronjbaptiste - 2 months ago 11
C# Question

Avoid running function within Unit Test (NUnit)

Say I have a class:

public class SomeClass {

public Model _model;

public SomeClass() {
_model = new Model();
}

public void Foo() {
_model.DoSomethingHeavy();
}

}


And a Test:

[TestFixture]
public class SomeClassTest {

[Test]
public void TestFooCalledSomethingHeavy() {
SomeClass someClass = NSubstitute.Substitute.For<SomeClass>();
someClass.Foo();
someClass._model.Received().DoSomethingHeavy();
}
}


I'm trying to test that someClass.Foo(); called _model.DoSomethingHeavy() but I don't actually want DoSomethingHeavy to run. How would I do that? Or is this the wrong approach?

Answer

For overriding behavior of method with NSubstitute, the method need to be part of interface or virtual method.

First make sure that method DoSomethingHeavy marked as virtual or create interface(better -> gives more possibilities for testing) of Model class

public interface IModel
{
    void DoSomethingHeavy();
}

Implement interface in your Model class

public class Model : IModel
{
    public void DoSomethingHeavy()
    {
        // heavy staff
    }
}

Then, very important for testing -> remove responsibility for creating instance of Model outside of SomeClass

public class SomeClass 
{
    public Model _model { get; private set; }

    // Constructor will sure, that class get an instance of IModel
    public SomeClass(IModel model) 
    {
        _model = model; 
    }

    public void Foo() 
    {
        _model.DoSomethingHeavy();
    }
}

Now you can create fake of IModel and check that method DoSomethingHeavy executed without running real implementation.

Because SomeClass is class under the test, you don't need to mock it - you will test behavior of that class.

[Test]
public void TestFooCalledSomethingHeavy() 
{
    // Arrange
    IModel fakeModel = Substitute.For<IModel>();
    SomeClass someClass = new SomeClass(fakeModel); 

    // Act 
    someClass.Foo();  

    // Assert      
    fakeModel.Received().DoSomethingHeavy();
}
Comments