2011-07-26 29 views
6

Đây là tình huống. Tôi đã có cuộc gọi không đồng bộ nên tôi cần phải làm cho Hạng trung cho việc này để có thể kiểm tra nó.Xác định triển khai phương pháp trong đối tượng giả sử dụng Moq

request.BeginGetResponse(new AsyncCallback(LoginCallback), requestState); 

Vì vậy, để có thể kiểm tra điều này mà không có yêu cầu thực, tôi đã tạo giao diện mà tôi có thể giả lập.

public interface IRequestSender 
    { 
     void Send(HttpWebRequest request, AsyncCallback internalCallback, object requestState); 
    } 

Sau đó, trong thực hiện tôi có thể sử dụng cuộc gọi như một rằng ở trên và tôi có thể cung cấp một số lớp học giả để gọi phương thức callback của tôi bất kể yêu cầu hợp lệ hay không. Lớp giả của tôi trông như thế này.

public class RequestSenderMock : IRequestSender 
    { 
     public void Send(HttpWebRequest request, AsyncCallback internalCallback, object requestState) 
     { 
      var result = new Mock<IAsyncResult>(); 
      result.Setup(x => x.AsyncState).Returns(requestState); 
      internalCallback(result.Object); 
     } 
    } 

Bây giờ tôi có thể dễ dàng tạo đối tượng giả trong đơn vị thử nghiệm và sử dụng nó. Nhưng khi tôi tạo

var sender = new Mock<RequestSenderMock>(); 

Tôi không thể xác minh số cuộc gọi cho đối tượng này.

sender.Verify(x => x.Send(It.IsAny<HttpWebRequest>(), It.IsAny<AsyncCallback>(), It.IsAny<object>()), Times.Once()); 

Nó nói rằng phương pháp của tôi cần phải ảo. Có cách nào để làm điều này mà không làm cho phương pháp của tôi ảo không? Nó sẽ là tốt nhất nếu tôi bằng cách nào đó có thể chỉ định phương pháp impelementation khi sử dụng giao diện.

var sender = new Mock<IRequestSender>(); 

Và bằng cách nào đó bằng phương pháp Thiết lập hoặc một số phương pháp khác để thực hiện đối tượng giả này. Hơn tôi chỉ đơn giản là loại bỏ lớp giả của tôi. Điều này có khả thi không? Bạn có đề nghị gì?

Trả lời

8

Tôi thấy khó hiểu rằng bạn đang tạo mô hình thủ công và sử dụng khung mocking để giả lập nó (chế nhạo một mô hình). Tôi sẽ xem xét việc di chuyển các chức năng tùy chỉnh của bạn vào một số lớp tiện ích và sử dụng các cuộc gọi lại.

Ví dụ:

public class RequestSenderHelpers 
{ 
    public static void Send(HttpWebRequest request, AsyncCallback internalCallback, object requestState) 
    { 
     var result = new Mock<IAsyncResult>(); 
     result.Setup(x => x.AsyncState).Returns(requestState); 
     internalCallback(result.Object); 
    } 

} 

    [Test] 
    public void Callback_VerifyingWithMethodImplementation_VerifyWorks() 
    { 
     // arrange 
     var sender = new Mock<IRequestSender>(); 
     sender.Setup(s => s.Send(It.IsAny<HttpWebRequest>(), It.IsAny<AsyncCallback>(), It.IsAny<object>())).Callback<HttpWebRequest, AsyncCallback, object>(RequestSenderHelpers.Send); 

     // act 
     sender.Object.Send(null, delegate {}, null); 

     // assert 
     sender.Verify(s => s.Send(It.IsAny<HttpWebRequest>(), It.IsAny<AsyncCallback>(), It.IsAny<object>())); 
    } 

Để tránh việc thiết lập tiết bạn có thể quấn thiết lập của phương pháp này trong một phương pháp mở rộng và thay đổi thử nghiệm của bạn cho phù hợp:

public static class RequestSenderHelpers 
{ 
    public static void Send(HttpWebRequest request, AsyncCallback internalCallback, object requestState) 
    { 
     var result = new Mock<IAsyncResult>(); 
     result.Setup(x => x.AsyncState).Returns(requestState); 
     internalCallback(result.Object); 
    } 

    public static void SetupSendWithMockedAsyncResult(this Mock<IRequestSender> sender) 
    { 
     sender.Setup(s => s.Send(It.IsAny<HttpWebRequest>(), It.IsAny<AsyncCallback>(), It.IsAny<object>())).Callback<HttpWebRequest, AsyncCallback, object>(Send);    
    } 

} 

    [Test] 
    public void Callback_VerifyingWithMethodImplementation_VerifyWorks() 
    { 
     // arrange 
     var sender = new Mock<IRequestSender>(); 
     sender.SetupSendWithMockedAsyncResult(); 

     // act 
     sender.Object.Send(null, delegate {}, null); 

     // assert 
     sender.Verify(s => s.Send(It.IsAny<HttpWebRequest>(), It.IsAny<AsyncCallback>(), It.IsAny<object>())); 
    } 
+0

Cảm ơn, đó chính xác là những gì tôi cần. :) – Vajda

Các vấn đề liên quan