【发布时间】:2020-03-03 18:39:07
【问题描述】:
虽然我知道在对方法进行单元测试时,模拟它的所有依赖项非常重要,但我仍然对嵌套方法时会发生什么感到困惑?我是只模拟父方法的依赖关系,还是模拟子方法的依赖关系,还是对依赖对象的调用设置期望并设置确切的返回值,以便我可以执行测试我想要的?
例如,在下面的例子中,如果我们想对方法 B 进行单元测试,我们是只模拟 IHttpClientFactory 和 ILogger 还是我们也将方法的返回值设置为我们实际期望的值,否则当测试方法执行它继续并尝试在它失败的地方执行methodC,因为var client = _clientFactory.CreateClient()行执行后client的值为null?
using System.Net.Http;
...
public class classA
{
private readonly IHttpClientFactory _clientFactory;
private sting url = "...";
private ILogger _log { get; set; }
...
public classA(ILogger log, IHttpClientFactory clientFactory, ...)
{
_log = log;
_clientFactory = clientFactory;
...
}
public string methodB(string inputB)
{
var varB = methodC(inputB);
...
return ..;
}
public string methodC(string inputC)
{
...
var client = _clientFactory.CreateClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage httpResponseMessage = await client.PostAsync(url, new StringContent(inputC, Encoding.UTF8, "application/json"));
responJsonText = await httpResponseMessage.Content.ReadAsStringAsync();
...
return ..;
}
}
【问题讨论】:
-
它被称为单元测试,因为您测试单个单元 - 您可以在代码中找到的最小公共部分:f.i.一个类的方法。如果这个方法调用另一个方法(当然是同一个类,否则它会是一个你已经模拟的依赖项)那么你不应该关心,因为你也会为另一个方法编写一些单元测试:o)
-
另一方面,如果 methodB 会调用一些受保护的或私有的方法(同一个类),你会关心 - 从调用者的角度来看?不,您会期望该方法将按照记录的方式工作,并且您不会关心实现细节。这正是您使用单元测试测试的内容:该单元的行为是否符合记录
-
你只需要模拟你实际调用的方法,你不需要存根整个类。是的,您将模拟响应是您对测试用例的期望。无论测试中的特定单元需要什么来完成测试,mock 中的其他东西都不重要。
标签: c# unit-testing mocking moq