我在测试单身时遇到了一些问题。当我运行此代码时,我在TestGetLogicalDevices()中收到错误。 CallTo()失败,因为服务不是假对象。当我尝试创建一个假对象(注释代码)时,它会给出一个错误,因为RestService是一个带有私有构造函数的单例。如何创建这个单例的假对象?
private RestService service;
[TestInitialize]
public void Init()
{
//service = A.Fake<RestService>();
service = RestService.Instance;
service.CreateClient("test", "test");
}
[TestMethod]
public async Task TestGetLogicalDevices()
{
var logicalDevices = (List<LogicalDevice>)A.CollectionOfFake<LogicalDevice>(10);
A.CallTo(() => service.GetLogicalDevices()).Returns(Task.FromResult(logicalDevices));
List<LogicalDevice> collectedData = await service.GetLogicalDevices();
Assert.AreEqual(2, collectedData.Count);
}
public async Task<List<LogicalDevice>> GetLogicalDevices()
{
var response = await client.GetAsync(apiBaseUrl + "/logical-devices");
if (response.IsSuccessStatusCode)
{
var json = await response.Content.ReadAsStringAsync();
var logicalDevices = JsonConvert.DeserializeObject<List<LogicalDevice>>(json);
var sortedList = logicalDevices.OrderBy(logicalDevice => logicalDevice.Name).ToList();
return sortedList;
}
else
{
return null;
}
}
更新 我添加了我要测试的方法代码。也许有人有更好的测试建议?
答案 0 :(得分:3)
注意:我不确定我是否理解您要做的事情。你准备测试什么?在您的测试中,您将service.GetLogicalDevices()
配置为返回一些东西,然后调用service.GetLogicalDevices()
并断言它返回的内容(除非FakeItEasy被破坏,否则应该是您将其配置为返回的内容)。所以,你实际上没有测试服务......你正在测试模拟框架!像FakeItEasy这样的模拟框架对于模拟被测系统(SUT)的依赖性很有用,而不是SUT本身。在您的情况下,如果SUT为RestService
,则需要模拟RestService
的依赖关系,而不是RestService
本身。例如,您可以使用您控制的HttpClient
注入HttpMessageHandler
(有关详情,请参阅here)。
现在,回答你的实际问题(假设它真的RestService
你想假装):
当我运行此代码时,我在TestGetLogicalDevices()中收到错误。 CallTo()失败,因为服务不是虚假对象。
A.CallTo
仅适用于假货; FakeItEasy无法控制它没有创建的对象的行为。
当我尝试创建一个虚假对象(注释代码)时,它会出错,因为RestService是一个带有私有构造函数的单例
RestService
是一个类,FakeItEasy可以为类创建一个假,但它通过继承类来实现它,因此它需要一个可访问的构造函数。另外,请记住,只能配置虚拟方法。 GetLogicalDevices
不是虚拟的,因此假的不能覆盖其行为。
伪造RestService
有两个主要选项:
protected
而不是private
,并将方法设为虚拟,以便可以覆盖它们IRestService
界面&#34; RestService
类的,并伪造该接口而不是类。