如何模拟 OwinContext.Request.Query
How to mock 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
}
我正在使用 Moq 来模拟上下文。如何模拟 Query
类型为 IReadableStringCollection
的对象
如果你仔细看看IReadableStringCollection
,你会发现它继承自IEnumerable<KeyValuePair<string,string[]>
。我们还知道哪些其他 class/interface 继承自类似的东西。 IDictionary<TKey,TValue>
.
所以我着手寻找一种方法来模拟 IEnumerable<KeyValuePair<string,string[]>
。看看下面的扩展方法
public static class MockQueryableExtensions {
/// <summary>
/// Converts a generic <seealso cref="System.Collections.Generic.IEnumerable<T>"/> 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 查询与提供的假数据一起工作。
我知道你问过最小起订量,但我们使用 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);
}
我是这样弄的,想mock什么值就mock什么,
[TestMethod()]
public void GetRequestCorrelationIdTest()
{
Mock<IOwinContext> owinMock = new Mock<IOwinContext>(MockBehavior.Strict);
var requestMock = new Mock<IOwinRequest>();
var headers = new Mock<IHeaderDictionary>();
string valArr = "TestCorrelationId";
var keys = new Mock<ICollection<string>>(MockBehavior.Loose);
keys.Setup(m => m.Add("X-CorrelationId"));
headers.Setup(m=>m.Keys).Returns(keys.Object);
headers.Setup(m => m.Count).Returns(1);
requestMock.Setup(m => m.Headers).Returns(headers.Object);
requestMock.Setup(m => m.Headers["X-CorrelationId"]).Returns("TestCorrelationId");
owinMock.Setup(m => m.Request).Returns(requestMock.Object);
//Assigning the Context to the class
Utilities.OwinContext = owinMock.Object;
// Testing the code
var corelationId = Utilities.GetRequestCorrelationId();
Assert.AreEqual(corelationId, "valArr");
}
我正在尝试对检查 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 来模拟上下文。如何模拟 Query
类型为 IReadableStringCollection
如果你仔细看看IReadableStringCollection
,你会发现它继承自IEnumerable<KeyValuePair<string,string[]>
。我们还知道哪些其他 class/interface 继承自类似的东西。 IDictionary<TKey,TValue>
.
所以我着手寻找一种方法来模拟 IEnumerable<KeyValuePair<string,string[]>
。看看下面的扩展方法
public static class MockQueryableExtensions {
/// <summary>
/// Converts a generic <seealso cref="System.Collections.Generic.IEnumerable<T>"/> 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 查询与提供的假数据一起工作。
我知道你问过最小起订量,但我们使用 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);
}
我是这样弄的,想mock什么值就mock什么,
[TestMethod()]
public void GetRequestCorrelationIdTest()
{
Mock<IOwinContext> owinMock = new Mock<IOwinContext>(MockBehavior.Strict);
var requestMock = new Mock<IOwinRequest>();
var headers = new Mock<IHeaderDictionary>();
string valArr = "TestCorrelationId";
var keys = new Mock<ICollection<string>>(MockBehavior.Loose);
keys.Setup(m => m.Add("X-CorrelationId"));
headers.Setup(m=>m.Keys).Returns(keys.Object);
headers.Setup(m => m.Count).Returns(1);
requestMock.Setup(m => m.Headers).Returns(headers.Object);
requestMock.Setup(m => m.Headers["X-CorrelationId"]).Returns("TestCorrelationId");
owinMock.Setup(m => m.Request).Returns(requestMock.Object);
//Assigning the Context to the class
Utilities.OwinContext = owinMock.Object;
// Testing the code
var corelationId = Utilities.GetRequestCorrelationId();
Assert.AreEqual(corelationId, "valArr");
}