我在一个项目中遇到了这样一个方法,类似和简短的逻辑如下所示
public void BookAClass()
{
_eventPublisher.Publish(new BookReadyEvent());
//Using static class Reader to
//read a configured Storage Place
//to retrieve an ExamResultFile object
var examResultFile = Reader.ReadFile("xxxx");
var examResultLevel = _analyzer.AnalyseExameFile(examResultFile);
if(examResultLevel == ExamResultEnum.Pass)
{
_eventPublisher.Publish(new BookCancelEvent());
}
else//examResultLevel == ExamResultEnum.Failed
{
_eventPublisher.Publish(new BookStartingEvent());
//TODO
}
}我尝试实现两个条件的单元测试: Pass和失败。关于通行证条件
[TestMethod()]
public void BookAClass_Pass_ExecuteAll()
{
var analyzerService = new Mock<AnalyzerService>();
analyzerService.Setup(analyzer =>
analyzer.AnalyseExameFile(new ExamResultFile()))
.Returns(ExamResultEnum.Pass);
var student = new Student(analyzerService.Object);
student.BookAClass();
}毫无疑问,单元测试失败了,因为AnalyseExameFile将接受来自Reader.ReadFile("xxxx")响应的对象,而不是我的假数据,这导致examResultLevel每次都为空。因此,将永远不会触发Pass条件。
我知道最好将examResultFile作为输入参数,而不是从BookAClass中调用的方法返回的对象。但实际情况要复杂得多,所以我现在无法重构它。
我想知道是否有任何解决方案来实现这种情况下的单元测试?
发布于 2022-05-10 10:40:05
是的,您可以告诉Moq忽略您提供的参数(因此考虑为所有可能的参数完成设置)。
在最简单的情况下,您可以编写:
analyzerService.Setup(analyzer =>
analyzer.AnalyseExameFile(It.IsAny<ExamResultFile>()))
.Returns(ExamResultEnum.Pass);这表明,无论参数如何,此设置都将用于AnalyseExameFile的任何调用。在高级场景中,也可以这样做。
analyzerService.Setup(analyzer =>
analyzer.AnalyseExameFile(It.Is<ExamResultFile>(x => x.Name == "Hans")))
.Returns(ExamResultEnum.Pass);这使用函式来定义参数是否应该匹配。
如果您将模拟创建为var analyzerService = new Mock<AnalyzerService>(MockBehavior.Strict);,您将被告知一个调用缺少的设置(一个默认返回null,在您的情况下)。
发布于 2022-05-10 10:42:27
您可以使用ExamResultFile函数来确保与传递给AnalyseExameFile的任何参数匹配,而不是传递新的AnalyseExameFile实例。
analyzerService.Setup(analyzer =>
analyzer.AnalyseExameFile(It.IsAny<ExamResultFile>()))
.Returns(ExamResultEnum.Pass);https://stackoverflow.com/questions/72184552
复制相似问题