2013-06-21 21 views
0

我试图测试,使得两个连续的Web请求的方法。如何嘲笑两个连续的Web请求

到现在为止,我只用this solution using an object called TestWebRequest测试单个请求和工作方式类似于单请求的魅力。如果您不熟悉它,TestWebRequest会拦截Web请求机制并在现场后面工作以返回预期响应。这使得可以在不使用模拟的情况下测试实际的服务。

不过现在我的方法之一的逻辑已经变为这样的事情(在伪代码)

public void MakePayment(PaymentRequest request) 
{ 
    var statusRequest = webService.GetPaymentStatus(new PaymentStatusRequest() 
      { 
       OrderId = request.OrderId 
      }); 

    if (statusRequest.StatusId != 100) 
    { 
    var responseXml = webService.GetResponse(GetRequestXml(request)); 
    /*.. process response ..*/ 
    } 
} 

有没有一种方法来扩展TestWebRequest处理两个请求,或者是有,我可以用另一种测试这种方法?

这里是一个工作试验的例子:

[Test] 
public void MakePayment() 
{ 
     var response = @"<XML>..</XML>"; 
     TestWebRequest request = TestWebRequestCreate.CreateTestRequest(response); 
     var result = webService.MakePayment(1, new PaymentRequest()); 
     var expectedResponse = new PaymentResponse() 
     { 
      Status = 23 
     }; 
     Assert.AreEqual(expectedResponse, result); 
} 

现在,如果MakePayment突然提出了两个要求,那么我们就需要一种方式来嘲笑像这两假冒回复:

[Test] 
public void MakePayment() 
{ 
     var response1 = @"<XML>..</XML>"; 
     var response2 = @"<XML>..</XML>"; 
     TestWebRequest request1 = TestWebRequestCreate.CreateTestRequest(response1); 
     TestWebRequest request2= TestWebRequestCreate.CreateTestRequest(response2); 
     var result = webService.MakePayment(1, new PaymentRequest()); 
     var expectedResponse = new PaymentResponse() 
     { 
      Status = 23 
     }; 
     Assert.AreEqual(expectedResponse, result); 
} 

哪个没有按没有工作。

在此先感谢

+0

你可以发布你想测试,而不是伪的实际代码?我有一个答案,但有太多的假设,我不得不作出,因为我第二次猜测你实际测试 – levelnis

+0

我刚刚发布的实际代码。我只是在同一个方法中创建两个Web请求。如果我创建一个,那么测试通过,但如果我创建两个,那么TestWebRequest将返回相同的响应。我不能让它以特定的顺序返回两个不同的响应 – Nick

回答

0

我把它通过更新TestWebReqestCreate工厂方法接受两个请求工作。

这里是更新的代码。这不是很优雅,但适用于两个请求,并且您不必为单个请求更改所有现有测试。

我想这可以更新到链中的任何数量的请求,但我并不需要做的,所以我现在想出了快速。

我希望帮助别人谁被卡住了像我这样的

internal class TestWebRequestCreate : IWebRequestCreate 
    { 
     static WebRequest nextRequest; 
     static WebRequest nextRequest2; 
     private static bool used = false; 
     static object lockObject = new object(); 

     static public WebRequest NextRequest 
     { 
      get { return nextRequest; } 
      set 
      { 
       lock (lockObject) 
       { 
        nextRequest = value; 
       } 
      } 
     } 

     /// <summary>See <see cref="IWebRequestCreate.Create"/>.</summary> 
     public WebRequest Create(Uri uri) 
     { 
      if (used) 
      { 
       return nextRequest2; 
      } 
      else 
      { 
       used = true; 
       return nextRequest; 
      } 
     } 

     /// <summary>Utility method for creating a TestWebRequest and setting 
     /// it to be the next WebRequest to use. It can now accept a subsequent request</summary> 
     /// <param name="response1">The response the TestWebRequest will return.</param> 
     /// <param name="response2">The subsequent response the TestWebRequest will return.</param> 
     public static TestWebRequest CreateTestRequest(string response1, string response2 = null) 
     { 
      TestWebRequest request1 = new TestWebRequest(response1); 
      used = false; 
      nextRequest = request1; 

      if (!string.IsNullOrEmpty(response2)) 
      { 
       TestWebRequest request2 = new TestWebRequest(response2); 
       nextRequest2 = request2; 
      } 

      return request1; 
     } 
    } 
0

您是否测试过您作为工作测试给出的示例?这不会通过,因为expectedResponse是你的测试代码进行实例化,不能是同一个对象从webService.MakePayment调用返回的一个。你链接的文章是测试2个字符串是否相等,而不是2个复杂类型。您也实际上并未使用您在测试中实例化的TestWebRequest对象。

也就是说,通过控制2个创建的请求并将其传递给2个调用webRequest.MakePayment或使用Moq的回调功能,您可以完成要测试的内容,未经测试的代码):

webRequestMock.Setup(x => x.MakePayment(1, It.IsAny<PaymentRequest>()).Returns(It.IsAny<PaymentResponse>()).CallBack((PaymentRequest request, PaymentResponse response) => VerifyResponse(request, response)); 

private void VerifyResponse(PaymentRequest request, PaymentResponse response) 
{ 
    // do some checks to determine whether it's the first call or the second, based on something uniquely different between to 2 requests - I need more actual code from you before I can tidy this up 
    // e.g. (pseudocode) 
    if (request.SomeValue == firstRequestValue) 
    { 
     response.ShouldEqual(firstReponse); 
    } 
    else 
    { 
     response.ShouldEqual(secondReponse); 
    } 

} 

我说,这是未经测试的代码,因为我不知道返回的响应是否可以被捕获并传递到回调(因为它是返回值)与否。

+0

webRequest不是一个模拟,它是实际的服务,这是因为我正在测试它。 TestWebRequest在webRequest服务内部使用,所以当它试图发布XML时,TestWebRequest将返回预期的responseXML。 这是测试Web服务的一个非常聪明的方式,但我无法扩展它来处理多个请求 – Nick