使用 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);
}
我不确定如何测试这个
你目前的测试方法对我来说毫无意义。
如果您正在测试实现 IRestClient
的 RestClient
class,则不需要模拟 IRestClient
本身。您需要模拟所有外部依赖项 - 您已经为 IHttpWebRequestFactory
创建了模拟,现在您需要将其注入到测试对象中。我没有看到你的 class 的其余部分,但我假设你的 WebRequest
对象是 IHttpWebRequestFactory
类型 - 你需要将你的工厂模拟分配给它。
现在您需要定义测试用例。我可以很快看到以下内容(但你可以有更多原因):
- StatusCode 不正确。
- StatusCode 正常,但 responseStream 为空。
- StatusCode 正常,responseStream 不为空,方法执行成功。
- 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);
我想使用 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);
}
我不确定如何测试这个
你目前的测试方法对我来说毫无意义。
如果您正在测试实现 IRestClient
的 RestClient
class,则不需要模拟 IRestClient
本身。您需要模拟所有外部依赖项 - 您已经为 IHttpWebRequestFactory
创建了模拟,现在您需要将其注入到测试对象中。我没有看到你的 class 的其余部分,但我假设你的 WebRequest
对象是 IHttpWebRequestFactory
类型 - 你需要将你的工厂模拟分配给它。
现在您需要定义测试用例。我可以很快看到以下内容(但你可以有更多原因):
- StatusCode 不正确。
- StatusCode 正常,但 responseStream 为空。
- StatusCode 正常,responseStream 不为空,方法执行成功。
- 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);