gpt4 book ai didi

c# - 使用 Autofac 为同一类中的内部方法编写 Moq 单元测试

转载 作者:行者123 更新时间:2023-11-30 20:46:35 30 4
gpt4 key购买 nike

我正在尝试在同一个类中模拟内部方法。但是我的模拟失败了。

这是我的代码。

界面

public interface IStudentService
{
int GetRank(int studentId);
IList<Subject> GetSubjects(int studentId);
}

实现

public class StudentService : IStudentService
{
private readonly IStudentRepository _studentRepository;
private readonly ISubjectRepository _subjectRepository;

public StudentService(IStudentRepository studentRepository, ISubjectRepository subjectRepository)
{
_studentRepository = studentRepository;
_subjectRepository = subjectRepository;
}

public int GetRank(int studentId)
{
IList<Subject> subjects = GetSubjects(studentId);

int rank = 0;
//
//Calculate Rank
//
return rank;
}

public virtual IList<Subject> GetSubjects(int studentId)
{
return _subjectRepository.GetAll(studentId);
}
}

单元测试

[TestFixture]
public class StudentServiceTest
{
[SetUp]
public void Setup()
{

}

[TearDown]
public void TearDown()
{

}

[Test]
public void GetRankTest()
{
using (var mock = AutoMock.GetStrict())
{
var mockStudentService = new Mock<IStudentService>();
mockStudentService.Setup(x => x.GetSubjects(1)).Returns(new ServiceResponse<SystemUser>(new List<Subject>{ new AccounProfile(), new AccounProfile()}));
mock.Provide(mockStudentService.Object);

var component = mock.Create<StudentService>();
int rank = component.GetRank(1);
mockStudentService.VerifyAll();

Assert.AreEqual(1, rank, "GetRank method fails");
}
}
}

当我调试代码时,它并没有模拟 GetSubjects 方法。它实际上进入了那个方法。我正在使用 Nunit、Moq 和 Autofac 编写单元测试。

提前致谢!

最佳答案

有两种解决方案。

1。部分模拟

在这种方法中,您创建正在测试的组件的模拟 (StudentService) 并告诉 Moq 模拟它的一些方法 (GetSubjects -- to- be-mocked 方法必须是虚拟的),同时将其他方法(GetRank)委托(delegate)给 base implementation :

Setting mock.CallBase = true instructs Moq to delegate any call not matched by explicit Setup call to its base implementation.

// mockStudentService is not needed, we use partial mock
var service = mock.Create<StudentService>();
service.CallBase = true;
service.Setup(m => m.GetSubjects(1)).Returns(...);

var rank = service.GetRank(1);
// you don't need .VerifyAll call, you didn't not set any expectations on mock
Assert.AreEqual(1, rank, "GetRank method fails");

2。模拟内部服务 (ISubjectRepository)

部分模拟是为特殊情况保留的。你的情况比较常见。您的组件 (StudentService) 可以依赖模拟的 ISubjectRepository 为其提供主题,而不是模拟自身:

using (var mock = AutoMock.GetStrict())
{
var subjectRepositoryMock = new Mock<ISubjectRepository>();
subjectRepositoryMock.Setup(x => x.GetSubjects(1)).Returns(...);
mock.Provide(subjectRepositoryMock.Object);

var component = mock.Create<StudentService>();
int rank = component.GetRank(1);
// verify is not needed once again

Assert.AreEqual(1, rank, "GetRank method fails");
}

关于c# - 使用 Autofac 为同一类中的内部方法编写 Moq 单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26713367/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com