2016-07-04 74 views
0

我試圖單元測試這OwinContext.Request.Query檢查查詢和改變它如何嘲笑OwinContext.Request.Query

public static async Task SetUpQuery(IOwinContext context, IClientStore clientConfig) 
{ 
    // Get the ClientId from Querystring 
    var clientIdQs = context.Request.Query.Where(x => x.Key == Constants.AuthorizeRequest.ClientId).Select(x => x.Value).FirstOrDefault(); 
    // Some more code here 
} 

我使用起訂量嘲笑情境的方法。如何嘲笑Query對象,它是類型IReadableStringCollection

回答

3

的如果你把在IReadableStringCollection仔細看看,你會看到,它從IEnumerable<KeyValuePair<string,string[]>繼承。我們知道還有哪些類/接口繼承了類似的東西。 IDictionary<TKey,TValue>

所以我着手尋找一種方法來模擬IEnumerable<KeyValuePair<string,string[]>。看看下面的擴展方法

public static class MockQueryableExtensions { 
    /// <summary> 
    /// Converts a generic <seealso cref="System.Collections.Generic.IEnumerable&lt;T&gt;"/> to a <see cref="Moq.Mock"/> implementation of Quarable list 
    /// </summary> 
    public static Mock<T> AsQuaryableMock<T, TItem>(this Mock<T> quaryableMock, IEnumerable<TItem> list) 
     where T : class,IEnumerable<TItem> { 

     var queryableList = list.AsQueryable(); 

     quaryableMock.As<IQueryable<TItem>>().Setup(x => x.Provider).Returns(queryableList.Provider); 
     quaryableMock.As<IQueryable<TItem>>().Setup(x => x.Expression).Returns(queryableList.Expression); 
     quaryableMock.As<IQueryable<TItem>>().Setup(x => x.ElementType).Returns(queryableList.ElementType); 
     quaryableMock.As<IQueryable<TItem>>().Setup(x => x.GetEnumerator()).Returns(queryableList.GetEnumerator()); 

     return quaryableMock; 
    } 
} 

做完這些所有剩下是確保創建一些假的數據,將其存儲在一個字典,將它安放的IReadableStringCollection

[TestClass] 
public class OwinContextTests { 
    [TestMethod] 
    public void Mock_OwinContext_Request_Query_Should_Be_Queryable() { 
     //Arrange 
     var collection = new Dictionary<string, string[]>() { 
      {"A", new[]{"1", "2", "3"} }, 
      {"B", new[]{"4", "5", "6"} } 
     }; 
     //applying extension method 
     var queryMock = new Mock<IReadableStringCollection>().AsQuaryableMock(collection); 

     var requestMock = Mock.Create<IOwinRequest>(); 

     requestMock.Setup(m => m.Query).Returns(queryMock.Object); 

     var contextMock = Mock.Create<IOwinContext>(); 
     contextMock.Setup(m => m.Request).Returns(requestMock.Object); 

     var key = "B"; 
     var expected = collection[key]; 

     //Act 
     var actual = SetUpQuery(contextMock.Object, key); 

     //Assert 
     Assert.IsNotNull(actual); 
     CollectionAssert.AreEqual(expected, actual); 

    } 

    public static string[] SetUpQuery(IOwinContext context, string Key) { 
     // Get the values from Querystring 
     var values = context.Request.Query.Where(x => x.Key == Key).Select(x => x.Value).FirstOrDefault(); 
     return values; 
    } 

} 
模擬

上述測試通過了在上下文請求查詢上調用的linq查詢與提供的假數據一起工作。

+0

這個工作很好 – Shetty

1

我知道你問過關於moq的問題,但我們用typemock這使得測試更簡單。我會把它放在這裏讓其他開發者可以選擇

[TestMethod,Isolated] 
public void Isolate_OwinContext_Request_Query_Should_Be_Queryable() 
{ 
    // Arrange 
    var key = Constants.AuthorizeRequest.ClientId; 
    var collection = new Dictionary<string, string[]>() { 
     {key, new[]{"1", "2", "3"} }, 
     {"B", new[]{"4", "5", "6"} } 
    }; 

    // Can it be simpler than this? 
    var fakeContext = Isolate.Fake.Instance<IOwinContext>(); 
    Isolate.WhenCalled(() => fakeContext.Request.Query). 
     WillReturnCollectionValuesOf(collection.AsQueryable()); 

    // Act 
    var result = Program.SetUpQuery(fakeContext, null); 

    // Assert 
    CollectionAssert.AreEquivalent(collection[key], result); 

}