2015-02-24 85 views
7

我想要做模擬擴展方法,但它不起作用。如何才能做到這一點?NSubstitute模擬擴展方法

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 }); 
} 
+2

AFAIK你不能用免費的嘲笑框架嘲笑擴展方法。因爲擴展方法只是靜態方法,所以你不能用免費的嘲諷框架來嘲笑靜態方法。 TypeMock這樣做我認爲(但這超出了問題)。 – 2015-02-24 10:56:30

回答

3

NSubstitute無法根據Sriram的評論模擬擴展方法,但仍然可以將模擬參數傳遞給擴展方法。

在這種情況下,Random類具有虛擬方法,所以我們可以直接使用NSubstitute和其他基於DynamicProxy的嘲笑工具來嘲笑它。 (對於NSubstitute尤其是我們需要非常小心嘲諷類。請仔細閱讀在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); 
    } 
} 
+0

我試過這個,但模擬不返回{1,2,3},但進入代碼/ * ... * /。見[gist](https://gist.github.com/anonymous/a27d3bd572d8abdaf4770805b93eefdb) – Damian 2017-06-16 09:05:04

+0

@Damian它只在擴展方法調用模擬對象時才起作用。在要點中,'NextInt32s()'需要調用'random.Next(minInclusive,maxInclusive)'。 – 2017-06-16 09:12:44

+0

在dotnet框架中,Random.Next(min,max)返回一個int值,而不是int數組。 C#的新警告! – Damian 2017-06-16 12:16:14

-1

根據SOLID原理依賴倒置定義了較低級模型不應當取決於高級模型而是取決於抽象像接口和嘲笑概念主要用來模擬接口,使得低電平型號未經測試。

+0

是的,但如果我爲DefaultRandom定義接口並模擬他,那麼它看不到擴展方法NextInt32s。我能怎麼做? – user3526923 2015-02-24 14:56:08

0

,如果你創建這樣一個接口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<IRandom>(); 
var result = randomizer.NextInt32s(3,0,10); 

通過這個過程中你只是嘲諷接口而不是實際的類。