Mock单元测试疑问:如何获取被调用的接口实现类信息
解决Mock接口时无法追踪真实实现类的问题
首先得明确一个核心点:你用new Mock<IUser>()创建的不是AdminUser或NormalUser的实例!Mock框架(看起来是Moq)会动态生成一个实现了IUser接口的代理类,这个类和你自己写的两个实现类完全无关,这就是为什么你的断点根本不会触发——代码里根本没调用到AdminUser或NormalUser的逻辑。
下面分几种情况给你解决思路:
1. 如果你想测试真实的AdminUser/NormalUser实现
那你根本不需要Mock!直接实例化真实的类就行:
// 测试AdminUser var adminUser = new AdminUser(); adminUser.Get("username"); // 这里断点会触发在AdminUser的Get方法里 // 测试NormalUser var normalUser = new NormalUser(); normalUser.Get("username");
2. 如果你确实需要Mock,但想验证调用细节
如果你是用Mock来模拟IUser的行为,想确认方法是否被调用、传入的参数是否正确,可以用Mock框架的验证功能:
var mockUser = new Mock<IUser>(); // 调用方法 mockUser.Object.Get("test-username"); // 验证Get方法是否被调用了一次,且参数是"test-username" mockUser.Verify(u => u.Get("test-username"), Times.Once);
在调试时,你也可以查看mockUser.Object.GetType(),它会显示Mock生成的代理类类型(比如Moq用Castle动态代理的话,会是类似Castle.Proxies.IUserProxy的类型)。
3. 想让Mock模拟真实实现类的行为
如果你希望Mock的行为和AdminUser/NormalUser一致,可以把真实类的逻辑注入到Mock的Setup里:
var mockUser = new Mock<IUser>(); // 让Mock的Get方法调用AdminUser的真实逻辑 mockUser.Setup(u => u.Get(It.IsAny<string>())) .Returns((string username) => new AdminUser().Get(username));
这样当你调用mockUser.Object.Get("username")时,会执行AdminUser的Get方法,此时AdminUser里的断点就会触发了。
4. 如果是依赖注入场景想确认注入的是哪个实现类
如果你的代码是通过依赖注入容器(比如Autofac、Microsoft DI)来注入IUser实例的,你可以:
- 在调试时,查看注入实例的
GetType()属性,直接看到是AdminUser还是NormalUser - 在AdminUser和NormalUser的构造函数里添加日志输出(比如
Console.WriteLine("AdminUser 实例已创建")),这样运行时就能知道哪个类被实例化了
内容的提问来源于stack exchange,提问作者learntogrow-growtolearn
相关产品推荐
相关产品推荐

