使用 Moq 测试 API 服务时出现解析问题
Parsing problem while testing API Services with Moq
我正在尝试使用 Moq 测试我的 API,但我在模拟服务和测试执行方面遇到了问题。
单元测试代码:
public class UnitTest1
{
private readonly INearEarthObjectService _repo;
Mock<INearEarthObjectService> _mockRepo = new Mock<INearEarthObjectService>();
public UnitTest1()
{
var services = new ServiceCollection();
services.AddTransient<INearEarthObjectService, NearEarthObjectService>();
services.AddTransient(sp => new HttpClient { BaseAddress = new Uri("https://api.nasa.gov/neo/rest/v1/") });
var serviceProvider = services.BuildServiceProvider();
_repo = serviceProvider.GetService<INearEarthObjectService>();
}
[Fact]
public async void Test1()
{
_mockRepo.Setup(p => p.GetAllNeos(2)).Returns(Task.FromResult<IEnumerable<NearEarthObjectDTO>>).Verifiable();
var result = _mockRepo.Object.GetAllNeos(2);
Assert.True(result.IsCompletedSuccessfully);
}
}
我在 行:
中遇到问题
var result = _mockRepo.Object.GetAllNeos(2);
我给了我这个例外:
System.ArgumentException: 'Object of type 'System.Int32' cannot be converted to type 'System.Collections.Generic.IEnumerable`1[NasaApi.Models.NearEarthObjectDTO]'.'
我的服务代码是否有用:
public async Task<IEnumerable<NearEarthObjectDTO>> GetAllNeos(int days)
{
//Variable declaration
HttpClient client = new HttpClient();
DateTime today = DateTime.Now;
DateTime nextday = today.AddDays(days);
List<NearEarthObjectDTO> list = new List<NearEarthObjectDTO>();
NearEarthObjectDTO neo;
//URL parsing & data request
var complete_url = url + start_date_param + today.Date.ToString(
"yyyy-MM-dd") + "&" + end_date_param + nextday.Date.ToString("yyyy-MM-dd") + "&" + detailed_param + "&" + api_key_param;
var feed = await client.GetFromJsonAsync<Rootobject>(complete_url);
//Data filtering and parsing into DTO
if (feed != null)
{
foreach (var register in feed.near_earth_objects)
{
foreach(var item in register.Value)
{
neo = new NearEarthObjectDTO();
neo.Id = item.id;
neo.Nombre = item.name;
neo.Fecha = item.close_approach_data[0].close_approach_date;
neo.Velocidad = item.close_approach_data[0].relative_velocity.kilometers_per_hour;
neo.Diametro = DiameterCalc.Calc(item.estimated_diameter.meters.estimated_diameter_min,
item.estimated_diameter.meters.estimated_diameter_min);
neo.Planeta = item.close_approach_data[0].orbiting_body;
if (item.is_potentially_hazardous_asteroid && neo.Planeta.Equals("Earth") && !list.Contains(neo))
{
list.Add(neo);
}
}
}
}
//Return just the top 3 biggest potentially hazardous asteroids
return list.OrderByDescending(x => x.Diametro).Take(3);
}
我不知道解析问题在哪里,因为我正在使用一个应该适应任何类型的 var。
您没有测试模拟对象。您的模拟设置应该类似于
_mockRepo.Setup(p => p.GetAllNeos(It.IsAny<int>)).ReturnsAsync(new List<NearEarthObjectDTO>()).Verifiable();
这里你说的是当 GetAllNeos() 被任何 int
调用时它应该 return 我的 List
(这将是 GetAllNeos() 函数的一些假数据return)
我正在尝试使用 Moq 测试我的 API,但我在模拟服务和测试执行方面遇到了问题。
单元测试代码:
public class UnitTest1
{
private readonly INearEarthObjectService _repo;
Mock<INearEarthObjectService> _mockRepo = new Mock<INearEarthObjectService>();
public UnitTest1()
{
var services = new ServiceCollection();
services.AddTransient<INearEarthObjectService, NearEarthObjectService>();
services.AddTransient(sp => new HttpClient { BaseAddress = new Uri("https://api.nasa.gov/neo/rest/v1/") });
var serviceProvider = services.BuildServiceProvider();
_repo = serviceProvider.GetService<INearEarthObjectService>();
}
[Fact]
public async void Test1()
{
_mockRepo.Setup(p => p.GetAllNeos(2)).Returns(Task.FromResult<IEnumerable<NearEarthObjectDTO>>).Verifiable();
var result = _mockRepo.Object.GetAllNeos(2);
Assert.True(result.IsCompletedSuccessfully);
}
}
我在 行:
中遇到问题var result = _mockRepo.Object.GetAllNeos(2);
我给了我这个例外:
System.ArgumentException: 'Object of type 'System.Int32' cannot be converted to type 'System.Collections.Generic.IEnumerable`1[NasaApi.Models.NearEarthObjectDTO]'.'
我的服务代码是否有用:
public async Task<IEnumerable<NearEarthObjectDTO>> GetAllNeos(int days)
{
//Variable declaration
HttpClient client = new HttpClient();
DateTime today = DateTime.Now;
DateTime nextday = today.AddDays(days);
List<NearEarthObjectDTO> list = new List<NearEarthObjectDTO>();
NearEarthObjectDTO neo;
//URL parsing & data request
var complete_url = url + start_date_param + today.Date.ToString(
"yyyy-MM-dd") + "&" + end_date_param + nextday.Date.ToString("yyyy-MM-dd") + "&" + detailed_param + "&" + api_key_param;
var feed = await client.GetFromJsonAsync<Rootobject>(complete_url);
//Data filtering and parsing into DTO
if (feed != null)
{
foreach (var register in feed.near_earth_objects)
{
foreach(var item in register.Value)
{
neo = new NearEarthObjectDTO();
neo.Id = item.id;
neo.Nombre = item.name;
neo.Fecha = item.close_approach_data[0].close_approach_date;
neo.Velocidad = item.close_approach_data[0].relative_velocity.kilometers_per_hour;
neo.Diametro = DiameterCalc.Calc(item.estimated_diameter.meters.estimated_diameter_min,
item.estimated_diameter.meters.estimated_diameter_min);
neo.Planeta = item.close_approach_data[0].orbiting_body;
if (item.is_potentially_hazardous_asteroid && neo.Planeta.Equals("Earth") && !list.Contains(neo))
{
list.Add(neo);
}
}
}
}
//Return just the top 3 biggest potentially hazardous asteroids
return list.OrderByDescending(x => x.Diametro).Take(3);
}
我不知道解析问题在哪里,因为我正在使用一个应该适应任何类型的 var。
您没有测试模拟对象。您的模拟设置应该类似于
_mockRepo.Setup(p => p.GetAllNeos(It.IsAny<int>)).ReturnsAsync(new List<NearEarthObjectDTO>()).Verifiable();
这里你说的是当 GetAllNeos() 被任何 int
调用时它应该 return 我的 List
(这将是 GetAllNeos() 函数的一些假数据return)