unit-testing - 使用 xUnit 和 Moq 对 ASP.Net Core Web API 进行单元测试
问题描述
我正在尝试使用 xUnit 和 Moq 测试我的 Web API。我已经使用构造函数实例化了所有必需的模拟存储库实例。我还在构造函数中实例化了控制器。控制器实例正在成功调用操作方法。但不在我的存储库中执行功能。
public class SubjectControllerTest
{
public Mock<IHostingEnvironment> HostingEnvironment { get; set; }
private readonly Mock<ILogger<SubjectController>> _logger;
private readonly Mock<ISubjectManager<Subject>> _subjectManager;
private readonly Mock<IChapterManager<Chapter>> _chapterManager;
private readonly Mock<ITopicManager<Topic>> _topicManager;
private readonly Mock<ILearningPointManager<LearningPoint>> _learningPointManager;
private SubjectController controller;
public SubjectControllerTest()
{
_subjectManager = new Mock<ISubjectManager<Subject>>();
_chapterManager = new Mock<IChapterManager<Chapter>>();
_topicManager = new Mock<ITopicManager<Topic>>();
_learningPointManager = new Mock<ILearningPointManager<LearningPoint>>();
_logger = new Mock<ILogger<SubjectController>>();
HostingEnvironment = new Mock<IHostingEnvironment>();
controller = new SubjectController(_subjectManager.Object, _chapterManager.Object,
_topicManager.Object, _learningPointManager.Object, HostingEnvironment.Object, _logger.Object);
}
[Fact]
public void Test_GetSubjectList()
{
var subject1 = new Subject
{
Subject_ID = 1,
Subject_Name = "Physics",
Subject_Photo_Url = null,
Validity_Start_Date = Convert.ToDateTime("2/2/2018 12:00:00 AM"),
Validity_End_Date = Convert.ToDateTime("12/25/2018 12:00:00 AM")
};
var subject2 = new Subject
{
Subject_ID = 2,
Subject_Name = "Business",
Subject_Photo_Url = null,
Validity_Start_Date = Convert.ToDateTime("3/10/2018 12:00:00 AM"),
Validity_End_Date = Convert.ToDateTime("3/20/2018 12:00:00 AM")
};
var subject3 = new Subject
{
Subject_ID = 3,
Subject_Name = "Math",
Subject_Photo_Url = "",
Validity_Start_Date = Convert.ToDateTime("7/8/2018 8:33:23 AM"),
Validity_End_Date = Convert.ToDateTime("5/8/2019 8:33:23 AM")
};
List<Subject> subjectList = new List<Subject>();
subjectList.Add(subject1);
subjectList.Add(subject2);
subjectList.Add(subject3);
int totalPages = 0;
_subjectManager.Setup(x => x.GetList(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<string>(), It.IsAny<string>(), ref totalPages))
.Returns(subjectList);
// Act
var result = controller.GetSubjectList(1, 5, string.Empty, string.Empty);
// Assert
var okResult = Assert.IsType<JsonResult>(result);
var viewModel = Assert.IsType<Paging>(okResult.Value);
var list = viewModel.Data as List<Subject>;
Assert.Equal(3, list.Count);
}
}
我在GetSubjectList
这里调用了动作方法。该方法已成功调用,但未GetList()
执行存储库方法。我的 API 如下。
可能是什么问题?
[HttpGet]
[Route("api/subjects")]
public IActionResult GetSubjectList(int page, int pageSize, string search, string sort)
{
try
{
if (search == null)
search = "";
if (sort == null)
sort = "";
int totalPages = 0;
List<Subject> list = _subjectManager.GetList(page, pageSize, sort, search, ref totalPages).ToList();
Paging result = new Paging { Data = list, Total = totalPages };
return Json(result);
}
catch (Exception ex)
{
throw new Exception(ex.Message, ex);
}
}
解决方案
由于被测方法中使用的实例不同,因此设置ref totalPages
的参数不匹配。仅当调用的ref参数与设置期间使用的实例相同时,它才会匹配。
如果使用 Moq 4.8 或更高版本,请使用It.Ref<T>.IsAny
_subjectManager
.Setup(_ => _.GetList(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<string>(), It.IsAny<string>(), ref It.Ref<int>.Any))
.Returns(subjectList);
这样,当调用模拟成员时,它将匹配请求的参数并按预期运行。
推荐阅读
- php - 如何在 ubuntu 18 & PHP7.3 中安装 mailparse
- python-3.x - 如何在熊猫数据透视表数据框中添加列的总计
- java - Flux:过滤异常
- findbugs - 使用 Gradle 插件运行时 Spotbugs XML 报告没有 instanceHash 值
- sql - 循环模式仅对某些数字返回错误值
- android - 运行应用程序时找不到 EasyPermissions 库错误?
- python - 处理组合,但某些元素不能一起使用
- python - 如何控制格式化字符串中浮点数的小数
- react-native - 无法在箭头功能内的组件上使用导航。未定义不是对象(评估“n.props.navigation”)
- python - SQLalchemy join 得到 A 不在 B