ASP.NET Core基于XUnit与NSubstitute的字符串传参逻辑单元测试问询
单元测试实现步骤
1. 前置准备:安装依赖NuGet包
先在你的单元测试项目中安装以下依赖包:
xunitxunit.runner.visualstudioNSubstituteMicrosoft.AspNetCore.Http.Abstractions(用于提供HttpContext相关类型支持)
2. 测试思路
我们一共需要覆盖3种业务场景:
- 两个判断条件同时为真:验证
DoSthElse被调用时传入的是特殊字符串 - 第一个判断条件为假:验证
DoSthElse被调用时传入的是普通字符串 - 第一个判断条件为真、第二个为假:验证
DoSthElse被调用时传入的是普通字符串
注:你提供的原始代码里
GetSpecialString方法的ToString后面缺少括号,需要先补上避免编译错误。
3. 测试代码示例
假设你要测试的服务类名为YourService,上下文类为MyContext,我们采用NSubstitute的部分模拟功能来控制方法返回值,测试代码如下:
using Xunit; using NSubstitute; using Microsoft.AspNetCore.Http; // 待测试的业务类示例,仅展示相关成员 public class YourService { public virtual async Task Func(MyContext context) { var stringToBeUsed = GetNormalString(context); if (FirstConditionFulfilled(context) && SecondConditionFulfilled(context)) { stringToBeUsed = GetSpecialString(context); } await DoSthElse(context, stringToBeUsed ); } public virtual string GetNormalString(MyContext context) => context.HttpContext.DoSthToGetNormalString().ToString(); public virtual string GetSpecialString(MyContext context) => context.HttpContext.DoSthToGetSpecialString().ToString(); public virtual bool FirstConditionFulfilled(MyContext context) => /* 原有业务逻辑 */; public virtual bool SecondConditionFulfilled(MyContext context) => /* 原有业务逻辑 */; public virtual Task DoSthElse(MyContext context, string str) => Task.CompletedTask; } // 自定义上下文类示例 public class MyContext { public HttpContext HttpContext { get; set; } } // 单元测试类 public class YourServiceTests { private readonly YourService _testService; private readonly MyContext _mockContext; private readonly HttpContext _mockHttpContext; private const string NormalString = "测试用普通字符串"; private const string SpecialString = "测试用特殊字符串"; public YourServiceTests() { // 初始化部分模拟的业务类实例 _testService = Substitute.ForPartsOf<YourService>(); // 模拟上下文和HttpContext对象 _mockContext = Substitute.For<MyContext>(); _mockHttpContext = Substitute.For<HttpContext>(); _mockContext.HttpContext.Returns(_mockHttpContext); // 配置HttpContext两个字符串获取方法的固定返回值 _mockHttpContext.DoSthToGetNormalString().Returns(NormalString); _mockHttpContext.DoSthToGetSpecialString().Returns(SpecialString); } [Fact] public async Task Func_双条件同时满足时_传入特殊字符串() { // Arrange:配置两个条件都返回真 _testService.FirstConditionFulfilled(_mockContext).Returns(true); _testService.SecondConditionFulfilled(_mockContext).Returns(true); // Act await _testService.Func(_mockContext); // Assert:验证DoSthElse收到的是特殊字符串 await _testService.Received(1).DoSthElse(_mockContext, SpecialString); } [Fact] public async Task Func_第一个条件不满足时_传入普通字符串() { // Arrange:第一个条件返回假,第二个条件任意 _testService.FirstConditionFulfilled(_mockContext).Returns(false); _testService.SecondConditionFulfilled(_mockContext).Returns(true); // Act await _testService.Func(_mockContext); // Assert:验证DoSthElse收到的是普通字符串 await _testService.Received(1).DoSthElse(_mockContext, NormalString); } [Fact] public async Task Func_第二个条件不满足时_传入普通字符串() { // Arrange:第一个条件返回真,第二个返回假 _testService.FirstConditionFulfilled(_mockContext).Returns(true); _testService.SecondConditionFulfilled(_mockContext).Returns(false); // Act await _testService.Func(_mockContext); // Assert:验证DoSthElse收到的是普通字符串 await _testService.Received(1).DoSthElse(_mockContext, NormalString); } }
注意事项
- 如果
FirstConditionFulfilled、DoSthElse这类逻辑属于独立的依赖服务,不需要使用部分模拟,直接模拟对应的依赖实例注入到测试服务即可。 - 如果你的上下文是ASP.NET Core自带的类型(比如FilterContext、EndpointContext等),直接用NSubstitute模拟对应类型即可,无需自定义上下文类。
内容的提问来源于stack exchange,提问作者Noelia
相关产品推荐
相关产品推荐

