NSubstitute模拟扩展方法

我想做模拟扩展方法,但它不起作用。 如何才能做到这一点?

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

 [Fact] public void Select() { var randomizer = Substitute.For(); randomizer.NextInt32s(3, 1, 10).Returns(new int[] { 1, 2, 3 }); } 

根据Sriram的注释,NSubstitute不能模拟扩展方法,但你仍然可以将一个模拟参数传递给扩展方法。

在这种情况下, Random类具有虚方法,因此我们可以直接使用NSubstitute和其他基于DynamicProxy的模拟工具来模拟它。 (特别是对于NSubstitute,我们需要非常小心地模拟类。请阅读文档中的警告。)

 public static class RandomExtensions { public static IEnumerable 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(); randomizer.Next(min, max).Returns(1, 2, 3); var result = randomizer.NextInt32s(3, 0, 10).ToArray(); Assert.AreEqual(new[] {1, 2, 3}, result); } } 

是的,如果您创建一个接口(如IRandom并扩展接口而不是实际实现,则可以进行模拟。 然后你应该可以模拟测试类中的接口。

 public interface IRandom { } public class Random : IRandom { } public static class RandomExtensions { public static string NextInt32s( this IRandom random, int neededValuesNumber, int minInclusive, int maxExclusive) { } } 

在您的测试类中添加:

 IRandom randomizer = Substitute.For(); var result = randomizer.NextInt32s(3,0,10); 

通过这个过程,你只是在模拟界面而不是实际的类。

根据SOLID原则,依赖性反演定义了较低级别的模型不应该依赖于高级模型,而是依赖于类似接口的抽象,而模拟概念主要用于模拟接口,以便不测试低级模型。