diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ViewResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ViewResultTest.cs index 5721e49304..9e744129f8 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ViewResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ViewResultTest.cs @@ -15,6 +15,9 @@ namespace Microsoft.AspNet.Mvc.Core.Test { public class ViewResultTest { + // The buffer size of the StreamWriter used in ViewResult. + private const int ViewResultStreamWriterBufferSize = 1024; + [Fact] public async Task ExecuteResultAsync_WritesOutputWithoutBOM() { @@ -51,5 +54,46 @@ namespace Microsoft.AspNet.Mvc.Core.Test // Assert Assert.Equal(expected, memoryStream.ToArray()); } + + // The StreamWriter used by ViewResult an internal buffer and consequently anything written to this buffer + // prior to it filling up will not be written to the underlying stream once an exception is thrown. + [Theory] + [InlineData(30, 0)] + [InlineData(ViewResultStreamWriterBufferSize + 30, ViewResultStreamWriterBufferSize)] + public async Task ExecuteResultAsync_DoesNotWriteToResponse_OnceExceptionIsThrown(int writtenLength, int expectedLength) + { + // Arrange + var longString = new string('a', writtenLength); + var memoryStream = new MemoryStream(); + var response = new Mock(); + response.SetupGet(r => r.Body) + .Returns(memoryStream); + var context = new Mock(); + context.SetupGet(c => c.Response) + .Returns(response.Object); + var routeDictionary = new Dictionary(); + var actionContext = new ActionContext(context.Object, + Mock.Of(), + routeDictionary, + new ActionDescriptor()); + var view = new Mock(); + view.Setup(v => v.RenderAsync(It.IsAny())) + .Callback((ViewContext v) => + { + v.Writer.Write(longString); + throw new Exception(); + }); + var serviceProvider = Mock.Of(); + var viewEngine = new Mock(); + viewEngine.Setup(v => v.FindView(routeDictionary, It.IsAny())) + .Returns(ViewEngineResult.Found("MyView", view.Object)); + var viewResult = new ViewResult(serviceProvider, viewEngine.Object); + + // Act + await Record.ExceptionAsync(() => viewResult.ExecuteResultAsync(actionContext)); + + // Assert + Assert.Equal(expectedLength, memoryStream.Length); + } } } \ No newline at end of file