2012-08-28 93 views
3

我想用對象來返回不同對象的序列。 例如:NSubstitute多個返回序列

var http = Substitute.For<IHttp>(); 
http.GetResponse(Arg.Any<string>()).Returns(resourceString, resourceString2); 
http.GetResponse(Arg.Any<string>()).Returns(x => { throw new Exception(); }); 

將返回資源字符串,然後resourceString2則例外。

或者是這樣的:

var http = Substitute.For<IHttp>(); 
http.GetResponse(Arg.Any<string>()).Returns(resourceString, x => { throw new Exception(); }, resourceString2); 

將返回資源字符串,然後再除外resourceString2。

我該怎麼做?

+0

我做了[拉請求(https://github.com/nsubstitute/NSubstitute/pull/100)至NSubstitute支持這一點。 –

回答

9

NSubstitute中的multiple returns語法僅支持值。爲了也拋出異常,您需要將函數傳遞給Returns,並自己實現所需的邏輯(例如Returns(x => NextValue()))。

使用隊列有一個Moq sequences on Haacked's blog的相關示例。你可以做NSubstitute類似的事情(例如只有代碼,請使用您自己的風險:)):

public interface IFoo { int Bar(); } 

[Test] 
public void Example() { 
    var results = new Results<int>(1) 
        .Then(2) 
        .Then(3) 
        .Then(() => { throw new Exception("oops"); }); 
    var sub = Substitute.For<IFoo>(); 
    sub.Bar().Returns(x => results.Next()); 

    Assert.AreEqual(1, sub.Bar()); 
    Assert.AreEqual(2, sub.Bar()); 
    Assert.AreEqual(3, sub.Bar()); 
    Assert.Throws<Exception>(() => sub.Bar()); 
} 

public class Results<T> { 
    private readonly Queue<Func<T>> values = new Queue<Func<T>>(); 
    public Results(T result) { values.Enqueue(() => result); } 
    public Results<T> Then(T value) { return Then(() => value); } 
    public Results<T> Then(Func<T> value) { 
     values.Enqueue(value); 
     return this; 
    } 
    public T Next() { return values.Dequeue()(); } 
} 

希望這有助於。

+0

謝謝,這就是我所尋找的。 –

3

下面是一個沒有額外類的內聯函數的例子。如果你這樣做了很多,我可能會選擇單獨的課程。

[Test] 
public void WhenSomethingHappens() 
{ 
    var something = Substitute.For<ISomething>(); 
    int callCount = 0; 
    something.SomeCall().Returns(1, 2); 
    something.When(x => x.SomeCall()).Do(obj => { if (++callCount == 3) throw new Exception("Problem!"); }); 

    Assert.AreEqual(1, something.SomeCall()); 
    Assert.AreEqual(2, something.SomeCall()); 
    Assert.Throws<Exception>(() => something.SomeCall()); 
} 


public interface ISomething 
{ 
    int SomeCall(); 
} 
+0

謝謝,帶額外類的方式似乎更容易閱讀和實現。 –

0

另一個帶out參數的例子。 此外,在分離線程中定期調用函數時,有些場景是有用的。我們可以以不同的方式模擬/模擬每個呼叫。

List<AnyClass> items = new List<AnyClass>(); 

    mockIService.TryDoSth(out response).ReturnsForAnyArgs(p => 
      { 
       p[0] = items; 
       return true; 
      }, 
      p => 
      { 
       p[0] = items; 
       return true; 
      }, p => 
      { 
       throw new Exception("Problem!"); 
      }); 

bool TryDoSth(out List result);

5

這是NSubstitute支持的一個非常友好的界面。

這會是這樣的......

var http = Substitute.For<IHttp>(); 
http.GetResponse(Arg.Any<string>()).Returns(x => resourceString, x => resourceString2, x => { throw new Exception(); }); 

Documentation can be found here