public void ProcessRequestAsync_IfExceptionIsNotHttpResponseException_DisposesRequest() { // Arrange using (HttpRequestMessage request = CreateRequest()) using (SpyDisposable spy = new SpyDisposable()) { request.RegisterForDispose(spy); ExceptionDispatchInfo exceptionInfo = CreateExceptionInfo(CreateException()); IExceptionLogger logger = CreateDummyLogger(); IExceptionHandler handler = CreateDummyHandler(); HttpRouteExceptionHandler product = CreateProductUnderTest(exceptionInfo, logger, handler); Mock <HttpResponseBase> responseBaseMock = new Mock <HttpResponseBase>(); responseBaseMock.SetupGet(r => r.Cache).Returns(() => new Mock <HttpCachePolicyBase>().Object); HttpResponseBase responseBase = responseBaseMock.Object; HttpContextBase contextBase = CreateStubContextBase(responseBase); contextBase.SetHttpRequestMessage(request); // Act Task task = product.ProcessRequestAsync(contextBase); // Assert Assert.NotNull(task); task.WaitUntilCompleted(); Assert.Equal(TaskStatus.Faulted, task.Status); Assert.True(spy.Disposed); Assert.ThrowsObjectDisposed(() => request.Method = HttpMethod.Get, typeof(HttpRequestMessage).FullName); } }
public void ProcessRequestAsync_WritingResponseCanceled_CancelsRequest() { // Arrange using (HttpRequestMessage request = CreateRequest()) { ExceptionDispatchInfo exceptionInfo = CreateExceptionInfo(new HttpResponseException(HttpStatusCode.OK)); IExceptionLogger logger = CreateDummyLogger(); IExceptionHandler handler = CreateDummyHandler(); HttpRouteExceptionHandler product = CreateProductUnderTest(exceptionInfo, logger, handler); Mock <HttpRequestBase> requestBase = new Mock <HttpRequestBase>(MockBehavior.Strict); requestBase.Setup(r => r.Abort()).Verifiable(); Mock <HttpResponseBase> responseBase = new Mock <HttpResponseBase>(MockBehavior.Strict); responseBase.SetupSet(r => r.StatusCode = It.IsAny <int>()).Throws(new OperationCanceledException()); HttpContextBase contextBase = CreateStubContextBase(requestBase.Object, responseBase.Object); contextBase.SetHttpRequestMessage(request); // Act Task task = product.ProcessRequestAsync(contextBase); // Assert Assert.NotNull(task); task.WaitUntilCompleted(); Assert.Equal(TaskStatus.RanToCompletion, task.Status); requestBase.Verify(r => r.Abort(), Times.Once()); } }
public void ProcessRequestAsync_IfExceptionIsHttpResponseException_UsesExceptionResponse() { // Arrange HttpStatusCode expectedStatusCode = HttpStatusCode.Forbidden; using (HttpResponseMessage response = CreateResponse(expectedStatusCode)) using (HttpRequestMessage request = CreateRequest()) { ExceptionDispatchInfo exceptionInfo = CreateExceptionInfo(new HttpResponseException(response)); IExceptionLogger logger = CreateDummyLogger(); IExceptionHandler handler = CreateDummyHandler(); HttpRouteExceptionHandler product = CreateProductUnderTest(exceptionInfo, logger, handler); int statusCode = 0; Mock <HttpResponseBase> responseBaseMock = new Mock <HttpResponseBase>(); responseBaseMock.SetupSet(r => r.StatusCode = It.IsAny <int>()).Callback <int>((s) => statusCode = s); responseBaseMock.SetupGet(r => r.Cache).Returns(() => new Mock <HttpCachePolicyBase>().Object); HttpResponseBase responseBase = responseBaseMock.Object; HttpContextBase contextBase = CreateStubContextBase(responseBase); contextBase.SetHttpRequestMessage(request); // Act Task task = product.ProcessRequestAsync(contextBase); // Assert Assert.NotNull(task); task.WaitUntilCompleted(); Assert.Equal(TaskStatus.RanToCompletion, task.Status); Assert.Equal((int)expectedStatusCode, statusCode); } }
public void ProcessRequestAsync_IfHandlerDoesNotHandle_ReturnsTaskPropagatingException() { // Arrange Exception expectedException = CreateExceptionWithCallStack(); string expectedStackTrace = expectedException.StackTrace; ExceptionDispatchInfo exceptionInfo = CreateExceptionInfo(expectedException); IExceptionLogger logger = CreateStubExceptionLogger(); IExceptionHandler handler = CreateStubExceptionHandler(); HttpRouteExceptionHandler product = CreateProductUnderTest(exceptionInfo, logger, handler); HttpResponseBase responseBase = CreateStubResponseBase(); HttpContextBase contextBase = CreateStubContextBase(responseBase); using (HttpRequestMessage request = CreateRequest()) { contextBase.SetHttpRequestMessage(request); // Act Task task = product.ProcessRequestAsync(contextBase); // Assert Assert.NotNull(task); task.WaitUntilCompleted(); Assert.Equal(TaskStatus.Faulted, task.Status); Assert.NotNull(task.Exception); // Guard Exception exception = task.Exception.GetBaseException(); Assert.Same(expectedException, exception); Assert.NotNull(exception.StackTrace); Assert.True(exception.StackTrace.StartsWith(expectedStackTrace)); } }
public async Task ProcessRequestAsync_IfExceptionIsNotHttpResponseException_DisposesRequest() { // Arrange using (HttpRequestMessage request = CreateRequest()) using (SpyDisposable spy = new SpyDisposable()) { request.RegisterForDispose(spy); ExceptionDispatchInfo exceptionInfo = CreateExceptionInfo(CreateException()); Mock <IExceptionLogger> loggerMock = new Mock <IExceptionLogger>(MockBehavior.Strict); loggerMock .Setup(l => l.LogAsync(It.IsAny <ExceptionLoggerContext>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(0)); Mock <IExceptionHandler> handlerMock = new Mock <IExceptionHandler>(MockBehavior.Strict); handlerMock .Setup(h => h.HandleAsync(It.IsAny <ExceptionHandlerContext>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(0)); HttpRouteExceptionHandler product = CreateProductUnderTest(exceptionInfo, loggerMock.Object, handlerMock.Object); Mock <HttpResponseBase> responseBaseMock = new Mock <HttpResponseBase>(); responseBaseMock.SetupGet(r => r.Cache).Returns(() => new Mock <HttpCachePolicyBase>().Object); HttpResponseBase responseBase = responseBaseMock.Object; HttpContextBase contextBase = CreateStubContextBase(responseBase); contextBase.SetHttpRequestMessage(request); // Act & Assert await Assert.ThrowsAsync <Exception>(() => product.ProcessRequestAsync(contextBase)); Assert.True(spy.Disposed); Assert.ThrowsObjectDisposed(() => request.Method = HttpMethod.Get, typeof(HttpRequestMessage).FullName); } }
public async Task ProcessRequestAsync_IfHandlerDoesNotHandle_ReturnsTaskPropagatingException() { // Arrange Exception expectedException = CreateExceptionWithCallStack(); string expectedStackTrace = expectedException.StackTrace; ExceptionDispatchInfo exceptionInfo = CreateExceptionInfo(expectedException); IExceptionLogger logger = CreateStubExceptionLogger(); IExceptionHandler handler = CreateStubExceptionHandler(); HttpRouteExceptionHandler product = CreateProductUnderTest( exceptionInfo, logger, handler ); HttpResponseBase responseBase = CreateStubResponseBase(); HttpContextBase contextBase = CreateStubContextBase(responseBase); using (HttpRequestMessage request = CreateRequest()) { contextBase.SetHttpRequestMessage(request); // Act & Assert var exception = await Assert.ThrowsAsync <Exception>( () => product.ProcessRequestAsync(contextBase) ); Assert.Same(expectedException, exception); Assert.NotNull(exception.StackTrace); Assert.StartsWith(expectedStackTrace, exception.StackTrace); } }
public async Task ProcessRequestAsync_RouteCanceled_CancelsRequest() { // Arrange using (HttpRequestMessage request = CreateRequest()) { ExceptionDispatchInfo exceptionInfo = CreateExceptionInfo(new OperationCanceledException()); IExceptionLogger logger = CreateDummyLogger(); IExceptionHandler handler = CreateDummyHandler(); HttpRouteExceptionHandler product = CreateProductUnderTest(exceptionInfo, logger, handler); Mock <HttpRequestBase> requestBase = new Mock <HttpRequestBase>(MockBehavior.Strict); requestBase.Setup(r => r.Abort()).Verifiable(); Mock <HttpResponseBase> responseBase = new Mock <HttpResponseBase>(MockBehavior.Strict); HttpContextBase contextBase = CreateStubContextBase(requestBase.Object, responseBase.Object); contextBase.SetHttpRequestMessage(request); // Act await product.ProcessRequestAsync(contextBase); // Assert requestBase.Verify(r => r.Abort(), Times.Once()); } }
public async Task ProcessRequestAsync_IfExceptionIsHttpResponseException_DisposesRequestAndResponse() { // Arrange using (HttpResponseMessage response = CreateResponse()) using (HttpRequestMessage request = CreateRequest()) using (SpyDisposable spy = new SpyDisposable()) { request.RegisterForDispose(spy); ExceptionDispatchInfo exceptionInfo = CreateExceptionInfo(new HttpResponseException(response)); IExceptionLogger logger = CreateDummyLogger(); IExceptionHandler handler = CreateDummyHandler(); HttpRouteExceptionHandler product = CreateProductUnderTest(exceptionInfo, logger, handler); Mock <HttpResponseBase> responseBaseMock = new Mock <HttpResponseBase>(); responseBaseMock.SetupGet(r => r.Cache).Returns(() => new Mock <HttpCachePolicyBase>().Object); HttpResponseBase responseBase = responseBaseMock.Object; HttpContextBase contextBase = CreateStubContextBase(responseBase); contextBase.SetHttpRequestMessage(request); // Act await product.ProcessRequestAsync(contextBase); // Assert Assert.True(spy.Disposed); Assert.ThrowsObjectDisposed(() => request.Method = HttpMethod.Get, typeof(HttpRequestMessage).FullName); Assert.ThrowsObjectDisposed(() => response.StatusCode = HttpStatusCode.OK, typeof(HttpResponseMessage).FullName); } }
public async Task ProcessRequestAsync_IfExceptionIsNotHttpResponseException_CallsExceptionServices() { // Arrange Exception expectedException = CreateException(); ExceptionDispatchInfo exceptionInfo = CreateExceptionInfo(expectedException); Mock <IExceptionLogger> loggerMock = CreateStubExceptionLoggerMock(); IExceptionLogger logger = loggerMock.Object; Mock <IExceptionHandler> handlerMock = CreateStubExceptionHandlerMock(); IExceptionHandler handler = handlerMock.Object; HttpRouteExceptionHandler product = CreateProductUnderTest(exceptionInfo, logger, handler); HttpResponseBase responseBase = CreateStubResponseBase(); HttpContextBase contextBase = CreateStubContextBase(responseBase); using (HttpRequestMessage expectedRequest = new HttpRequestMessage()) { contextBase.SetHttpRequestMessage(expectedRequest); // Act & Assert await Assert.ThrowsAsync <Exception>(() => product.ProcessRequestAsync(contextBase)); Func <ExceptionContext, bool> exceptionContextMatches = (c) => c != null && c.Exception == expectedException && c.CatchBlock == WebHostExceptionCatchBlocks.HttpWebRoute && c.Request == expectedRequest; loggerMock.Verify(l => l.LogAsync(It.Is <ExceptionLoggerContext>(c => exceptionContextMatches(c.ExceptionContext)), CancellationToken.None), Times.Once()); handlerMock.Verify(l => l.HandleAsync(It.Is <ExceptionHandlerContext>(c => exceptionContextMatches(c.ExceptionContext)), CancellationToken.None), Times.Once()); } }
public async Task ProcessRequestAsync_IfHandlerHandles_UsesHandlerResult() { // Arrange ExceptionDispatchInfo exceptionInfo = CreateExceptionInfo(); IExceptionLogger logger = CreateStubExceptionLogger(); HttpStatusCode expectedStatusCode = HttpStatusCode.Ambiguous; Mock <IExceptionHandler> handlerMock = new Mock <IExceptionHandler>(MockBehavior.Strict); handlerMock .Setup( h => h.HandleAsync( It.IsAny <ExceptionHandlerContext>(), It.IsAny <CancellationToken>() ) ) .Returns <ExceptionHandlerContext, CancellationToken>( (c, i) => { c.Result = new StatusCodeResult( expectedStatusCode, new HttpRequestMessage() ); return(Task.FromResult(0)); } ); IExceptionHandler handler = handlerMock.Object; HttpRouteExceptionHandler product = CreateProductUnderTest( exceptionInfo, logger, handler ); int statusCode = 0; Mock <HttpResponseBase> responseBaseMock = new Mock <HttpResponseBase>(); responseBaseMock .SetupSet(r => r.StatusCode = It.IsAny <int>()) .Callback <int>((c) => statusCode = c); responseBaseMock .SetupGet(r => r.Cache) .Returns(() => new Mock <HttpCachePolicyBase>().Object); HttpResponseBase responseBase = responseBaseMock.Object; HttpContextBase contextBase = CreateStubContextBase(responseBase); using (HttpRequestMessage request = CreateRequest()) { contextBase.SetHttpRequestMessage(request); // Act await product.ProcessRequestAsync(contextBase); // Assert Assert.Equal((int)expectedStatusCode, statusCode); } }
public void ProcessRequestAsync_IfCopyToAsyncOnErrorResponseThrows_CallsExceptionLogger() { // Arrange Exception expectedOriginalException = CreateException(); ExceptionDispatchInfo exceptionInfo = CreateExceptionInfo(expectedOriginalException); Mock <IExceptionLogger> loggerMock = CreateStubExceptionLoggerMock(); IExceptionLogger logger = loggerMock.Object; Exception expectedErrorException = CreateException(); using (HttpResponseMessage expectedErrorResponse = new HttpResponseMessage()) using (HttpRequestMessage expectedRequest = new HttpRequestMessage()) { expectedErrorResponse.Content = CreateFaultingContent(expectedErrorException); Mock <IExceptionHandler> handlerMock = new Mock <IExceptionHandler>(MockBehavior.Strict); handlerMock .Setup(h => h.HandleAsync(It.IsAny <ExceptionHandlerContext>(), It.IsAny <CancellationToken>())) .Returns <ExceptionHandlerContext, CancellationToken>((c, i) => { c.Result = new ResponseMessageResult(expectedErrorResponse); return(Task.FromResult(0)); }); IExceptionHandler handler = handlerMock.Object; HttpRouteExceptionHandler product = CreateProductUnderTest(exceptionInfo, logger, handler); HttpResponseBase responseBase = CreateStubResponseBase(Stream.Null); HttpContextBase contextBase = CreateStubContextBase(responseBase); contextBase.SetHttpRequestMessage(expectedRequest); // Act Task task = product.ProcessRequestAsync(contextBase); // Assert Assert.NotNull(task); task.WaitUntilCompleted(); Assert.Equal(TaskStatus.RanToCompletion, task.Status); loggerMock.Verify(l => l.LogAsync(It.Is <ExceptionLoggerContext>(c => c.CanBeHandled == true && c.ExceptionContext != null && c.ExceptionContext.Exception == expectedOriginalException && c.ExceptionContext.CatchBlock == WebHostExceptionCatchBlocks.HttpWebRoute && c.ExceptionContext.Request == expectedRequest), CancellationToken.None), Times.Once()); loggerMock.Verify(l => l.LogAsync(It.Is <ExceptionLoggerContext>(c => c.CanBeHandled == false && c.ExceptionContext != null && c.ExceptionContext.Exception == expectedErrorException && c.ExceptionContext.CatchBlock == WebHostExceptionCatchBlocks.HttpControllerHandlerBufferError && c.ExceptionContext.Request == expectedRequest && c.ExceptionContext.Response == expectedErrorResponse), CancellationToken.None), Times.Once()); } }
public void ExceptionInfo_IfUsingExceptionInfoConstructor_ReturnsSpecifiedInstance() { // Arrange ExceptionDispatchInfo expectedExceptionInfo = CreateExceptionInfo(); HttpRouteExceptionHandler product = CreateProductUnderTest(expectedExceptionInfo); // Act ExceptionDispatchInfo exceptionInfo = product.ExceptionInfo; // Assert Assert.Same(exceptionInfo, expectedExceptionInfo); }
public void ExceptionHandler_IfUsingExceptionInfoConstructor_ReturnsExceptionServicesInstance() { // Arrange ExceptionDispatchInfo exceptionInfo = CreateExceptionInfo(); HttpRouteExceptionHandler product = CreateProductUnderTest(exceptionInfo); // Act IExceptionHandler handler = product.ExceptionHandler; // Assert IExceptionHandler expectedHandler = ExceptionServices.GetHandler(GlobalConfiguration.Configuration); Assert.Same(expectedHandler, handler); }
public void ExceptionHandler_ReturnsSpecifiedInstance() { // Arrange ExceptionDispatchInfo exceptionInfo = CreateExceptionInfo(); IExceptionLogger logger = CreateDummyLogger(); IExceptionHandler expectedHandler = CreateDummyHandler(); HttpRouteExceptionHandler product = CreateProductUnderTest(exceptionInfo, logger, expectedHandler); // Act IExceptionHandler handler = product.ExceptionHandler; // Assert Assert.Same(expectedHandler, handler); }
public void GetHttpHandler_ReturnsExceptionHandlerWithExceptionInfo() { // Arrange ExceptionDispatchInfo expectedExceptionInfo = CreateExceptionInfo(); IRouteHandler product = CreateProductUnderTest(expectedExceptionInfo); RequestContext requestContext = null; // Act IHttpHandler handler = product.GetHttpHandler(requestContext); // Assert HttpRouteExceptionHandler typedHandler = Assert.IsType <HttpRouteExceptionHandler>(handler); Assert.Same(expectedExceptionInfo, typedHandler.ExceptionInfo); }
public void ProcessRequestAsync_IfExceptionIsNotHttpResponseException_CallsExceptionServices() { // Arrange Exception expectedException = CreateException(); ExceptionDispatchInfo exceptionInfo = CreateExceptionInfo(expectedException); Mock <IExceptionLogger> loggerMock = CreateStubExceptionLoggerMock(); IExceptionLogger logger = loggerMock.Object; Mock <IExceptionHandler> handlerMock = CreateStubExceptionHandlerMock(); IExceptionHandler handler = handlerMock.Object; HttpRouteExceptionHandler product = CreateProductUnderTest(exceptionInfo, logger, handler); HttpResponseBase responseBase = CreateStubResponseBase(); HttpContextBase contextBase = CreateStubContextBase(responseBase); using (HttpRequestMessage expectedRequest = new HttpRequestMessage()) { contextBase.SetHttpRequestMessage(expectedRequest); // Act Task task = product.ProcessRequestAsync(contextBase); // Assert Assert.NotNull(task); task.WaitUntilCompleted(); Assert.Equal(TaskStatus.Faulted, task.Status); Func <ExceptionContext, bool> exceptionContextMatches = (c) => c != null && c.Exception == expectedException && c.CatchBlock == WebHostExceptionCatchBlocks.HttpWebRoute && c.Request == expectedRequest; loggerMock.Verify(l => l.LogAsync(It.Is <ExceptionLoggerContext>(c => c.CanBeHandled == true && exceptionContextMatches(c.ExceptionContext)), CancellationToken.None), Times.Once()); handlerMock.Verify(l => l.HandleAsync(It.Is <ExceptionHandlerContext>(c => exceptionContextMatches(c.ExceptionContext)), CancellationToken.None), Times.Once()); } }