NSubstitute之Substitute.For<T>

_currentUser = Substitute.For<ICurrentUser>();
这是 NSubstitute(一个 .NET 单元测试 mock 框架)中的标准用法,用来“创建一个假的 ICurrentUser 实例”。

下面详细解释它的逻辑。


到底发生了什么?

Substitute.For<T>() 的作用是:

创建一个可替代(mock)的 T 类型实例,这个实例可以记录调用、返回你设定的值、并用于断言。

所以:

_currentUser = Substitute.For<ICurrentUser>();

等价于:

“创建一个假的 ICurrentUser 对象,它实现所有 ICurrentUser 上的方法和属性,但行为都由我控制。”

也就是 mock / stub / fake。


🔍 这个 fake ICurrentUser 有什么能力?

它默认:

  • 所有属性、方法都会返回 默认值(如 null、0、false)。
  • 它可以记录“谁调用了我”。
  • 你可以给它设定返回值。
  • 你可以检查它是否收到某个调用。

例如:

✔️ 设定值

_currentUser.Id.Returns(Guid.Parse("..."));
_currentUser.UserName.Returns("John");

✔️ 测试某个方法是否调用过 ICurrentUser

await someService.DoWork();
_currentUser.Received().Id;  // 断言 Id 被访问过

✔️ 设定更复杂的行为

_currentUser.FindClaim("role").Returns(new Claim("role", "admin"));

🧠 为什么要这样写?

在 ABP 或 ASP.NET Core 中,ICurrentUser 是依赖注入来的,不可能在单元测试中依赖真实用户。

测试应该在无用户登录也能运行,或者测试“模拟登录”。

所以 NSubstitute 提供了这种 fake 来模拟各种情况:

例:模拟当前用户已登录:

_currentUser.IsAuthenticated.Returns(true);
_currentUser.UserName.Returns("Tester");

例:模拟当前用户没有权限:

_currentUser.GetId().Returns((Guid?)null);

📝 总结一句话

Substitute.For<ICurrentUser>() 会创建一个假的 ICurrentUser 对象,用于单元测试时替换真实的用户上下文,让你可以自由设置当前用户的各种属性与行为,并可断言调用状况。


posted @ 2025-11-15 22:35  JohnYang819  阅读(9)  评论(0)    收藏  举报