我可以模拟一个私有方法,或者测试这个POST方法的正确方法是什么
本文关键字:方法 POST 测试 是什么 或者 模拟 一个 有方法 我可以 | 更新日期: 2023-09-27 18:16:51
我有一个现有的ASP。. NET MVC应用程序,并想创建一些单元测试,我很快就遇到了下面的问题。是否有某种方法可以使用最小起订量,并说"当私有方法GETCLIENTIP运行时,然后返回xxx")?
因为现在它使用了HttpContext的部分,当然单元测试没有。
public HttpResponseMessage Post([FromBody]TriageCase TriageCase)
{
if (ModelState.IsValid)
{
//Get the IP address from the request
TriageCase.ipAddress = this.GetClientIP(Request);
_log.Info("IP Address = " + TriageCase.ipAddress);
}
}
public void Verify_Not_A_Suicide()
{
TriageCaseRepository repository = new TriageCaseRepository();
var controller = new TriageCasesController(repository);
//This will not work because I must mock a private method in the controller?
HttpResponseMessage result = controller.Post(new TriageCase());
}
有几种方法可以做到这一点,从令人讨厌的复杂方法到简单的折衷的方法。以下是一些:
- 可以使
GetClientIP
方法对HttpContext
不可知。然后把它变成内部的。控制器装配用InternalsVisibleTo
标记,并放置单元测试装配路径。
使HttpContext
的方法不可知可以使您避免使用HttpContextBase
(3.5以后的抽象http上下文类,用于启用测试)并提供mock等(顺便说一句,您应该考虑一下)。特别是对于MVC)将特定字符串作为参数传递给方法。例如:特定的服务器变量字符串。
- 你可以让
GetClientIP
方法接收HttpContextBase作为参数,然后使其内部。用InternalsVisibleTo
标记控制器组件,并放置单元测试组件路径。
在你的控制器动作中,你需要调用this.GetClientIP(new HttpContextWrapper(HttpContext.Current))
您的单元测试可以设置可模拟的上下文。更重要的是,您可以在上下文中设置期望,以确定是否调用了Request属性,或者是否进行了与ip地址相关的服务器变量调用。(更不用说直接的IP地址值验证了)
你可以使用FakeItEasy或Microsoft mole等来为私有方法创建私有访问器。我通常不会那样做。
你可以写一个基于
INetworkUtility
的接口,它有一个方法来给你IP地址。你的控制器可以使用这个接口。你可以有一个公共助手类来获取ip地址,它可以进行单元测试。
正如你所看到的,每个解决方案都有一些你需要做的权衡。
从Request对象获取IP地址是一个独立的逻辑,无论mvc或web api或asp web表单。(仍然是web特定的)所以把它作为辅助方法或基于接口的辅助方法是无害的。
就我个人而言,我更喜欢内部方法,(因为它几乎是私有的)并且不需要太多的代码更改。在适当的TDD方式中,您不会对"私有"或"内部"方法进行单元测试。在单元测试中只使用公共接口。如果你对私有/内部方法进行单元测试,那么你就把单元测试与特定的实现捆绑得太紧了。
应该做的是使用依赖注入来注入实现单元测试所需的"依赖"功能的类/接口。这将有助于进一步模块化您的代码,从而使其更容易维护。
一般不要尝试测试私有方法。它只是变得混乱-测试一个动作的输入和输出…
要么做依赖注入的事情,要么考虑一个"test double"或"accessor"类…
对于测试双 -使private
方法为protected
,然后您继承控制器并根据需要手动模拟输入或输出。我并不是说这比Ioc好还是差,我是说这是另一种方式。
protected virtual string ExecuteIpnResponse(string url)
{
var ipnClient = new WebClient();
var ipnResponse = ipnClient.DownloadString(url);
return ipnResponse;
}
我最近写了一篇关于这种测试风格的文章来检查paypal的呼叫。http://viridissoftware.wordpress.com/2014/07/29/paypal-ipn-payment-notification-example-in-c/