Использование следующего в качестве предмета примера промежуточного программного обеспечения для модульного тестирования
using RequestDelegate = Func<IOwinContext, Task>;
class MyMiddleware {
private readonly RequestDelegate next;
public MyMiddleware(RequestDelegate next) {
this.next = next;
}
public async Task Invoke(IOwinContext context) {
//The middleware is supposed to look at the cookies of the incoming request,
var request = context.Request;
var authenticated = request.User.Identity.IsAuthenticated;
var cookies = request.Cookies;
if (cookies["cookie-name"] != null) {
// 1. check for existence of a cookie on the incoming request.
//if the cookie exists, use its value to set a header,
//so that the pipline after this component thinks the header was always present.
request.Headers.Append("header-name", "header-value");
}
//2. call the next component.
await next.Invoke(context);
//3. on the way out, check for some conditions, and possibly set a cookie value.
if (authenticated) {
context.Response.Cookies.Append("cookie-name", "cookie-value");
}
}
}
и используя предоставленную информацию о желаемом поведении,
Было бы трудно провести модульное тестирование контроллера со всей сантехникой, необходимой для полного OwinContext
.
Вы уже указали множество ограничений на доступ к некоторым членам.
Однако Овин предоставляет множество абстракций, которые позволили бы имитировать / заглушать / подделывать желаемое поведение для изолированного модульного теста.
Следующий пример основан на предмете, представленном выше, и использует инфраструктуру Moq
mocking вместе с конкретными реализациями для правильной настройки и проведения изолированного модульного теста для промежуточного программного обеспечения объекта.
[TestClass]
public class OwinMiddlewareCookiesTest {
[Test]
public async Task MyMiddleware_Should_Set_RequestHeader_And_ResponseHeader() {
//Arrange
var cookieStore = new Dictionary<string, string> { { "cookie-name", "cookie-value" } };
var cookies = new RequestCookieCollection(cookieStore);
var request = Mock.Of<IOwinRequest>();
var requestMock = Mock.Get(request);
requestMock.Setup(_ => _.Cookies).Returns(cookies);
requestMock.Setup(_ => _.User.Identity.IsAuthenticated).Returns(true);
requestMock.Setup(_ => _.Headers.Append(It.IsAny<string>(), It.IsAny<string>()));
var response = new OwinResponse();
var context = Mock.Of<OwinContext>();
var contextMock = Mock.Get(context);
contextMock.CallBase = true;
contextMock.Setup(_ => _.Request).Returns(request);
contextMock.Setup(_ => _.Response).Returns(response);
RequestDelegate next = _ => Task.FromResult((object)null);
var myMiddleware = new MyMiddleware(next);
//Act
await myMiddleware.Invoke(context);
//Assert
requestMock.Verify(_ => _.Headers.Append("header-name", "header-value"));
response.Headers.ContainsKey("Set-Cookie");
}
}
Необходимо смоделировать только необходимые зависимости для завершения теста и проверки ожидаемого поведения.
И поскольку свойство Cookies
реализации запроса не может быть переопределено, необходимо использовать абстракцию. Это, однако, обеспечило большую гибкость в издевательстве над желаемым поведением.