使用 Moq 框架进行单元测试

Unit testing using Moq framework

我想使用 Moq 测试此方法。有人可以告诉我该怎么做吗? 我在查询字符串中附加了用户 ID 和值。如何在最小起订量中模仿这一点。 class 的名称是 RestClient.cs。我创建了一个名为 IRestClient 的接口。 public 接口 IRestClient { 字符串 MakeRequest(字符串用户 ID,字符串值); }

这是RestClient的makeRequest方法class

public string MakeRequest(string userId,string value)
{
     Logger.Info("Entering method MakeRequest()." + "Input Parameter: " + userId+Constant.NewLine+value);
     string strResponseValue = string.Empty;

     // The HttpWebRequest class allows you to programatically make web requests against an HTTP server.
     // create the WebRequest instantiated for making the request to the specified URI.
     HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Constant.webServerURI+"?id="+userId + Constant.UserValueAppend + value);

     //Gets or sets the method for the request.(Overrides WebRequest.Method.)
     request.Method = httpMethod.ToString();

     //Initially response from webserver is set to null.
     HttpWebResponse response = null;

     try
     {
         // Get the response in the response object of type HttpWebResponse
         // The request object of HttpWebRequest class is used to "get" the response (GetResponse()) from WebServer and store it in the response object
         response = (HttpWebResponse)request.GetResponse();

         // We check that the response StatusCode is good and we can proceed
         if (response.StatusCode != HttpStatusCode.OK)
         {
             Logger.Error("Error" + response.StatusCode.ToString());
             throw new ApplicationException(Constant.ErrorDisplay + response.StatusCode.ToString());
         }

         // Process the response string
         // We obtain the ResponseStream from the webserver using "get" (GetResponseStream())
         // The Stream Class provides a generic view of a sequence of bytes

         using (Stream responseStream = response.GetResponseStream())
         {
             if (responseStream != null)
             {
                 using (StreamReader reader = new StreamReader(responseStream))
                 {
                     //read the stream and store it in string strResponseValue
                     strResponseValue = reader.ReadToEnd();

                  }//End of StreamReader
             }
         }//End of using ResponseStream
     }// End of using Response

     catch (Exception ex)
     {
         Logger.Error("Error" + ex.Message.ToString());
         strResponseValue = ("Error " + ex.Message.ToString());
     }
     finally
     {
         if (response != null)
         {
             ((IDisposable)response).Dispose();
         }
     }
     //return the string strResponseValue
     Logger.Info("Leaving method MakeRequest." + "Output parameter: " + strResponseValue);
     return strResponseValue;
 }

这是我尝试在名为 RestClientTests.cs

的单元测试 class 中创建最小起订量
[TestMethod]
public void TestMethod1()
{
    var expected = "response content";
    var expectedBytes = Encoding.UTF8.GetBytes(expected);
    var responseStream = new MemoryStream();
    responseStream.Write(expectedBytes, 0, expectedBytes.Length);
    responseStream.Seek(0, SeekOrigin.Begin);

    var mockRestClient = new Mock<IRestClient>();
    var mockHttpRequest = new Mock<HttpWebRequest>();

    var response = new Mock<HttpWebResponse>();
    response.Setup(c => c.GetResponseStream()).Returns(responseStream);

    mockHttpRequest.Setup(c => c.GetResponse()).Returns(response.Object);

    var factory = new Mock<IHttpWebRequestFactory>();
    factory.Setup(c => c.Create(It.IsAny<string>())).Returns(mockHttpRequest.Object);

    var actualRequest = factory.Object.Create("http://localhost:8080");
    actualRequest.Method = WebRequestMethods.Http.Get;

    string actual;

    using (var httpWebResponse = (HttpWebResponse)actualRequest.GetResponse())
    {
        using (var streamReader = new StreamReader(httpWebResponse.GetResponseStream()))
        {
            actual = streamReader.ReadToEnd();
        }
    }

    mockRestClient.Setup(moq => moq.MakeRequest("xxx", "s")).Returns(actual);
}

我的 IhttpWebRequestFactory 界面如下所示:

interface IHttpWebRequestFactory
{
    HttpWebRequest Create(string uri);

}

我不确定如何测试这个

你目前的测试方法对我来说毫无意义。

如果您正在测试实现 IRestClientRestClient class,则不需要模拟 IRestClient 本身。您需要模拟所有外部依赖项 - 您已经为 IHttpWebRequestFactory 创建了模拟,现在您需要将其注入到测试对象中。我没有看到你的 class 的其余部分,但我假设你的 WebRequest 对象是 IHttpWebRequestFactory 类型 - 你需要将你的工厂模拟分配给它。

现在您需要定义测试用例。我可以很快看到以下内容(但你可以有更多原因):

  1. StatusCode 不正确。
  2. StatusCode 正常,但 responseStream 为空。
  3. StatusCode 正常,responseStream 不为空,方法执行成功。
  4. try 块中抛出异常。

现在,您需要为每个测试用例准备适当的设置和验证。例如,对于第一个,您需要您的模拟工厂 return 模拟请求,该请求将 return 模拟响应,结果代码不正确。现在你需要调用你的实际对象。作为验证,您需要检查是否抛出了 ApplicationException 以及是否实际调用了所有模拟。

好的,这是第二个测试用例的部分设置。它将准备模拟工厂,其中 returns 模拟请求,returns 模拟响应,OK 代码:

var response = new Mock<HttpWebResponse>();
response.SetupGet(c => c.StatusCode).Returns( HttpStatusCode.OK);

var mockHttpRequest = new Mock<HttpWebRequest>();
mockHttpRequest.Setup(c => c.GetResponse()).Returns(response.Object);

var factory = new Mock<IHttpWebRequestFactory>();
factory.Setup(c => c.Create(It.IsAny<string>))).Returns(mockHttpRequest.Object);