C# 我可以模拟一个私有方法吗?或者测试这个POST方法的正确方法是什么?
我有一个现有的ASP.NET MVC应用程序,想要创建一些单元测试,我很快遇到了下面的问题。是否有某种方式可以使用MOQ并说‘当运行私有方法GETCLIENTIP时,返回‘xxx’) 因为现在它使用的是HttpContext的一部分,当然单元测试没有C# 我可以模拟一个私有方法吗?或者测试这个POST方法的正确方法是什么?,c#,asp.net-mvc,unit-testing,mocking,moq,C#,Asp.net Mvc,Unit Testing,Mocking,Moq,我有一个现有的ASP.NET MVC应用程序,想要创建一些单元测试,我很快遇到了下面的问题。是否有某种方式可以使用MOQ并说‘当运行私有方法GETCLIENTIP时,返回‘xxx’) 因为现在它使用的是HttpContext的一部分,当然单元测试没有 public HttpResponseMessage Post([FromBody]TriageCase TriageCase) { if (ModelState.IsValid) { //Get the IP ad
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());
}
在适当的TDD方式中,您不需要单元测试“私有”或“内部”方法。单元测试中只使用公共接口。如果您对私有/内部方法进行单元测试,那么您将单元测试与特定实现捆绑得太紧
相反,应该做的是使用依赖注入来注入实现单元测试所需的“依赖”功能的类/接口。这将有助于进一步模块化您的代码,从而使其更易于维护。有几种方法可以做到这一点,从令人讨厌的复杂方法到简单的折衷方法。以下是一些:
- 可以使
的HttpContext
方法不可知。然后把它做成内部的。用GetClientIP
标记控制器组件,并放置单元测试组件路径InternalsVisibleTo
HttpContext
可以避免使用HttpContextBase
(3.5以后的抽象http上下文类,用于启用测试)并提供模拟等(顺便说一句,您应该考虑一下。特别是对于MVC),将特定字符串作为参数传递给方法。e、 g.特定的服务器变量字符串
- 您可以使
方法接收HttpContextBase作为参数,然后将其设置为内部。用GetClientIP
标记控制器组件,并放置单元测试组件路径李>InternalsVisibleTo
this.GetClientIP(新的HttpContextWrapper(HttpContext.Current))
单元测试可以设置可模拟的上下文。此外,您还可以在上下文中设置是否调用了请求属性,或者是否进行了与ip地址相关的服务器变量调用。(更不用说直接的ip地址值验证了)
- 您可以使用FakeiTesy或Microsoft Moles等为私有方法创建私有访问器。我通常不会这样做
- 您可以编写一个接口base
,它有一个方法为您提供IP地址。您的控制器可以使用此接口。它也可以单独测试INetworkUtility
- 您可以使用一个公共助手类来获取ip地址,该地址可以进行单元测试
就个人而言,我更喜欢内部方法(因为它几乎是私有的),并且不需要太多的代码更改 我一般不尝试测试私有方法。它只是变得混乱-测试一个动作的输入和输出 要么做依赖注入的事情,要么考虑一个“testdouble”或“accessor”类 对于双重测试-使
私有
方法a受保护
,然后继承控制器并根据需要手动模拟输入或输出。我不是说这比国际奥委会好还是坏,我是说这是另一种方式
protected virtual string ExecuteIpnResponse(string url)
{
var ipnClient = new WebClient();
var ipnResponse = ipnClient.DownloadString(url);
return ipnResponse;
}
我最近写了一篇关于这种测试风格的帖子,用于检查paypal呼叫。
你看过Fakeetisy吗?它应该能回答你的一些问题。尽管如此,ASP.NETMVC的调试难度是出了名的。考虑使用DI/IOC容器(如简单的注入器)注入某些逻辑块,这将使测试变得更容易。应用程序确实使用IOC作为控制器构造器库。但我想模仿的方法与此无关。。它只是一个使用了一些HttpContextI的私有方法,我看到添加它有帮助,但不确定为什么controller.Request=newHttpRequestMessage();