Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSubstitute mock extension method

I want to do mock extension method, but it does not work. How can this be done?

public static class RandomExtensions
{
    public static IEnumerable<int> NextInt32s(this System.Random random, int neededValuesNumber, int minInclusive, int maxExclusive)
    {
        // ...
    }
}

[Fact]
public void Select()
{
    var randomizer = Substitute.For<DefaultRandom>();
    randomizer.NextInt32s(3, 1, 10).Returns(new int[] { 1, 2, 3 });
}
like image 893
romanshoryn Avatar asked Feb 24 '15 10:02

romanshoryn


People also ask

How to mock random class with nsubstitute?

NSubstitute can not mock extension methods as per Sriram's comment, but you can still pass a mocked argument to an extension method. In this case, the Random class has virtual methods, so we can mock that directly with NSubstitute and other DynamicProxy-based mocking tools. (For NSubstitute in particular we need to be very careful mocking classes.

What is the difference between mock and nsubstitute?

With NSubstitute the concept is similar but with one noticeable change. There is no wrapper for the mock, we directly manipulate an instance of the interface we want to substitute.

How to mock a method in an extension method?

AFAIK you can't mock a extension method with free mocking frameworks. Because extension methods are just static methods, and you can't mock a static method with free mocking frameworks. TypeMock does this I think (but that's beyond the question).

How do you Mock a method in a non static method?

You can create a non-static method on a class that implements an interface, mock the method on the interface, and then create a extension method that acts as a wrapper around either the original method or the mocked method. Allow a class to call an extension method where we can mock out the implementation of what happens in that extension method


1 Answers

NSubstitute can not mock extension methods as per Sriram's comment, but you can still pass a mocked argument to an extension method.

In this case, the Random class has virtual methods, so we can mock that directly with NSubstitute and other DynamicProxy-based mocking tools. (For NSubstitute in particular we need to be very careful mocking classes. Please read the warning in the documentation.)

public static class RandomExtensions {
    public static IEnumerable<int> NextInt32s(this System.Random random, int neededValuesNumber, int minInclusive, int maxExclusive) { /* ... */ }
}
public class RandomExtensionsTests {
    [Test]
    public void Select()
    {
        const int min = 0, max = 10;
        var randomizer = Substitute.For<Random>();
        randomizer.Next(min, max).Returns(1, 2, 3);

        var result = randomizer.NextInt32s(3, 0, 10).ToArray();

        Assert.AreEqual(new[] {1, 2, 3}, result);
    }
}
like image 162
David Tchepak Avatar answered Sep 18 '22 02:09

David Tchepak