如何Mock C#中的ICourses复杂接口?
如何Mock ICourses接口
Mock接口的核心是直接设置其对外暴露的属性返回值,无需模拟实现类的内部逻辑。以下是两种完整的实现方案:
方案1:直接基于已有ICourse实例设置返回(推荐)
如果你的coursesData已经是可用的ICourse实例集合(比如实体类实现或匿名类),可以直接用它来配置Mock:
public Mock<ICourses> CreateCoursesMock(List<ICourse> coursesData, int selectedCurrentId) { var coursesMock = new Mock<ICourses>(); // 配置CurrentCourse返回匹配ID的课程 coursesMock.Setup(p => p.CurrentCourse) .Returns(coursesData.FirstOrDefault(c => c.Id == selectedCurrentId)); // 配置PreviousCourses返回排除当前ID的课程 coursesMock.Setup(p => p.PreviousCourses) .Returns(coursesData.Where(c => c.Id != selectedCurrentId)); return coursesMock; }
方案2:基于Mock集合设置返回
如果你需要单独Mock每个ICourse实例(比如要模拟属性的setter或其他行为),可以先将Mock<ICourse>转换为ICourse实例,再配置返回:
public Mock<ICourses> CreateCoursesMock(List<ICourse> coursesData, int selectedCurrentId) { var coursesMock = new Mock<ICourses>(); var coursesMockList = new List<Mock<ICourse>>(); foreach (var course in coursesData) { var courseMock = CreateCourseMock(course); coursesMockList.Add(courseMock); } // 将Mock集合转换为ICourse实例集合 var mockedCourses = coursesMockList.Select(m => m.Object).ToList(); // 配置CurrentCourse coursesMock.Setup(p => p.CurrentCourse) .Returns(mockedCourses.FirstOrDefault(c => c.Id == selectedCurrentId)); // 配置PreviousCourses coursesMock.Setup(p => p.PreviousCourses) .Returns(mockedCourses.Where(c => c.Id != selectedCurrentId)); return coursesMock; } // 配套的CreateCourseMock实现示例 public Mock<ICourse> CreateCourseMock(ICourse courseData) { var courseMock = new Mock<ICourse>(); // 使用SetupProperty确保属性可读写并设置初始值 courseMock.SetupProperty(c => c.Id, courseData.Id); courseMock.SetupProperty(c => c.CourseName, courseData.CourseName); courseMock.SetupProperty(c => c.DurationInMinutes, courseData.DurationInMinutes); return courseMock; }
关键注意事项
- 必须为方法添加返回语句
return coursesMock;,否则无法返回创建好的Mock实例 - 配置
Returns时,返回值类型必须与接口属性类型匹配:CurrentCourse返回ICourse,PreviousCourses返回IEnumerable<ICourse> - Mock接口只需关注对外暴露的成员,无需复刻实现类的私有字段逻辑
内容的提问来源于stack exchange,提问作者L. Kvri
相关产品推荐
相关产品推荐

