DEV Community

Naimul Karim
Naimul Karim

Posted on

Unit testing : How to Mock Public Methods in C# with NSubstitute

With NSubstitute, a public method can only be mocked if it is virtual (or abstract).
If the method is public but not virtual, NSubstitute cannot mock it.

The options to enables to mock it are :

1. Make the method virtual

This is the Minimal change and fully supported by NSubstitute

public class ProductService
{
    public virtual int GetPrice()
    {
        return 1;
    }
}
Enter fullscreen mode Exit fullscreen mode
var service = Substitute.For<MyService>();
service.GetValue().Returns(42);
Enter fullscreen mode Exit fullscreen mode

2. Extract an interface (cleanest design)

Refactor for Dependency Injection. Refactor your code so that the logic in the method is moved to a dependency (e.g., a helper/service class) that can be mocked. This is the best option.

public interface IProductService
{
    int GetPrice();
}
Enter fullscreen mode Exit fullscreen mode

Inject the interface and mock it instead.

var service = Substitute.For<IProductService>();
service.GetPrice().Returns(42);
Enter fullscreen mode Exit fullscreen mode

3. Use a wrapper / adapter (for third-party or legacy code)

public interface IProductServiceWrapper
{
    int GetPrice();
}

public class ProductServiceWrapper : IProductServiceWrapper
{
    private readonly ProductService _service;
    public int GetPrice() => _service.GetValue();
}
Enter fullscreen mode Exit fullscreen mode

Mock ProductServiceWrapper

Top comments (0)