2009-08-31 38 views
7

Tôi đang cố gắng tạo một thử nghiệm đơn vị cho một phương thức lấy đối tượng HttpResponse làm tham số. Cách làm đúng là gì? Tôi hy vọng bạn thử nghiệm đơn vị dày dạn ra có thể giúp tôi.Kiểm tra đơn vị cho một phương thức lấy đối tượng HttpResponse làm tham số. OutputStream không có sẵn

Thông tin bổ sung: Tôi đã thử tạo đối tượng HttpResponse giả bằng cách truyền trong StringWriter.

StringBuilder sb = new StringBuilder(); 
StringWriter sw = new StringWriter(sb); 
HttpResponse response = new HttpResponse(sw); 
RssGenerator.Generate(response, otherParameters); 

Xét nghiệm này không thành công với thông điệp: System.Web.HttpException: OutputStream là không có sẵn khi một TextWriter tùy chỉnh được sử dụng. Phương pháp được thử nghiệm là một phần của một thư viện lớp học. Nó sử dụng OutputStream của đối tượng Response để tạo một RSSFeed với một XMLWriter.

+0

Cảm ơn tất cả các câu trả lời tốt. Tôi sẽ cho bạn biết những gì tôi cuối cùng làm với điều này. –

Trả lời

12

Cần sử dụng System.Web.Abstractions namespace

Đặc biệt, phải mất một HttpResponseBase (http://msdn.microsoft.com/en-us/library/system.web.httpresponsebase.aspx) như là một tham số đầu vào thay vì HttpResponse. Sau đó, bạn có thể giả lập HttpResponseBase từ các bài kiểm tra của mình. Khi bạn có một HttpResponse thực để truyền vào, hãy sử dụng HttpResponseWrapper để tạo ra một HttpResponseBase.

+3

Tôi mất một lúc để tìm thấy điều này, vì vậy ở đây là: HttpResponseWrapper wrapper = new HttpResponseWrapper (this.Response); là cách làm những gì bạn mô tả. HttpResponseWrapper mở rộng HttpResponseBase. – Aligned

3

Để thực sự là đơn vị, bạn nên giả mạo HttpResponse và mọi thứ khác để chỉ kiểm tra mã phương thức của bạn. Tôi không biết về bất kỳ tiện ích nhại C# nào, nhưng điều này là question might help.

Sau đó bạn có thể làm một cái gì đó như thế này (ví dụ là Java với Mockito):

HttpResponse response = mock(HttpResponse.class); 
OutputStream outputStream = mock(OutputStream.class); 
when(response.getOutputStream()).thenReturn(outputStream); 

RssGenerator.generate(response, otherParameters); 

Tất nhiên, bạn có thể cần phải cấu hình mô hình của bạn nhiều hơn này, nhưng bạn sẽ có được ý tưởng chung.

1

Hàm khởi tạo cho HttpResponse không dành cho mục đích sử dụng của bạn, nó chỉ có trong chu trình trang ASP.NET để sử dụng, vì vậy không có tài liệu hướng dẫn về cách tạo.

Bạn phải thiết lập đối tượng HttpResponse để nó sử dụng một HttpWriter, nếu không nó sẽ không cho phép bạn truy cập luồng cơ bản. Tuy nhiên, hàm tạo đặt biến số _httpWriter thành null, vì vậy bạn phải tìm một số cách khác để đặt.

Bạn có thể sử dụng chương trình .NET Reflector để khám phá trong lớp HttpResponse và xem nó hoạt động như thế nào.

0

Nếu tôi không thể cấu trúc lại chữ ký phương thức (có lẽ phương thức thực sự chỉ cần một giá trị từ HttpResponse?), Tôi sẽ tạo Eclipse thực hiện null của HttpResponse (vâng, tôi đang sử dụng Java, nhưng đó là cùng ý tưởng) - tức là thực hiện tất cả các phương thức trả về null - và chỉ cần điền vào chỉ những cái tôi cần trong phương pháp được kiểm tra và yêu cầu chúng trả lại một số giá trị không đổi. (Vâng, cũng có thể sử dụng khung mocking của một số loại.)

Lý do bạn không thể tạo ví dụ thực hiện hiện tại của riêng mình là nó sẽ gắn liền với máy chủ ứng dụng của bạn và có thể sẽ cần tất cả các loại của gunk khác để thậm chí được instantiated.

Nếu hóa ra tôi cần một cái gì đó phức tạp hơn phiên bản đơn giản của HttpResponse, thì tôi sẽ KHÔNG xem xét phương pháp này trực tiếp: có lẽ một hoặc hai mức kiểm tra sẽ đơn giản hơn và sẽ cung cấp cho tôi cùng cấp niềm tin vào mã.

1

Vì vậy, vấn đề với Mocking HttpResponse là nó được niêm phong để bạn không thể mở rộng nó (và hầu hết các khuôn khổ mocking mà các lớp bê tông Mock chỉ ghi đè lên các phương thức ảo). Microsoft cũng đủ tử tế để không cung cấp giao diện cho hầu hết những thứ này ... vì vậy cảm ơn MS.Vì lý do này (trong số những người khác) tôi thường kết thúc bằng cách viết các giao diện của riêng tôi cho tất cả các lớp MS kín và sau đó viết các triển khai trình bao bọc lớp MS trong hàm khởi tạo và shunt chúng càng sớm càng tốt trong yêu cầu. Sau đó, bạn có thể tạo mocks của giao diện và yêu cầu họ làm bất cứ điều gì bạn thích.

1

Nếu bạn muốn có một câu trả lời chi tiết hơn, đây là những gì tôi đã kết thúc làm trong dự án của tôi:

_mockResponse = new Mock<HttpResponseBase>(); 
_contentType = string.Empty; 
_mockResponse.SetupSet(r => r.ContentType = It.IsAny<string>()).Callback<string>(value => _contentType = value); 
_header = new KeyValuePair<string, string>(); 
_mockResponse.Setup(r => r.AddHeader(It.IsAny<string>(), It.IsAny<string>())).Callback((string name, string value) => _header = new KeyValuePair<string, string>(name, value)); 
_writer = new StringBuilder(); 
_mockResponse.Setup(r => r.Write(It.IsAny<string>())).Callback<string>(s => _writer.Append(s)); 
var data = "This is the string to send as response"; 

UTIL.SendStringAsHttpResponse(data, _mockResponse.Object); 

Assert.That(_contentType, Is.EqualTo("application/CSV")); 
Assert.That(_header.Value, Is.EqualTo("attachment; filename=download.csv")); 
Assert.That(_writer.ToString(), Is.EqualTo(data)); 

nơi SendStringAsHttpResponse được định nghĩa là

public static void SendStringAsHttpResponse(string data, HttpResponseBase response) 
Các vấn đề liên quan