c# - 如何模拟 OwinContext.Request.Query

标签 c# unit-testing moq owin

我正在尝试对一种方法进行单元测试,该方法检查 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
}

我正在使用 Moq 来模拟上下文。如何模拟类型为 IReadableStringCollection

Query 对象

最佳答案

如果你仔细看看IReadableStringCollection ,你会看到它继承自 IEnumerable<KeyValuePair<string,string[]> .我们还知道哪些其他类/接口(interface)继承自类似的东西。 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 Queryable list 
    /// </summary>
    public static Mock<T> AsQueryableMock<T, TItem>(this Mock<T> queryableMock, IEnumerable<TItem> list)
        where T : class,IEnumerable<TItem> {

        var queryableList = list.AsQueryable();

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

        return queryableMock;
    }
}

完成后剩下的就是确保创建一些假数据,将其存储在字典中并将其设置在 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>().AsQueryableMock(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 查询与提供的假数据一起工作。

关于c# - 如何模拟 OwinContext.Request.Query,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38188009/

相关文章:

c# - 我需要重复的测试方法吗? 1 个用于单元测试,1 个用于集成测试?

c# - 接口(interface)中具有不同参数的策略模式 (C#)

c# - 使用 Visual Studio 扩展设置光标位置

c# - 解析 XML 响应并返回对象集合

c# - 如何将 Lazy<> 与 AutoMock (Moq) 一起使用

c# - Moq - 如何设置惰性界面

c# - 在 ASP.NET 中使用 Live Connect API 检索用户的电子邮件地址

swift - 在 Swift 中模拟 CLBeacon 对象

c# - 数据驱动的单元测试 - CSV 编码有问题吗?

java - 如何对具有相同数据的不同类的两个对象进行单元测试?