使用NSubstitute为Hangfire做单元测试并校验后台任务入参正确性
解决方案
你可以通过NSubstitute的参数匹配能力,直接解析Hangfire传入的表达式树,校验调用的方法和参数是否符合预期,无需依赖额外的第三方组件。
实现步骤
- 首先在单元测试中构造你预期传入的
SmsContent实例,作为参数校验的基准:
// 构造预期的入参对象,填充所有需要校验的字段 var expectedSmsContent = new SmsContent { Phone = "13800138000", Text = "测试短信内容", SendTime = DateTime.Now };
- 调用被测的
SendSms方法后,替换原来的调用次数校验代码,用以下方式同时校验调用次数、调用方法、入参正确性:
// 校验BackgroundJobClient的Enqueue方法被调用1次,且参数完全匹配预期 _backgroundJobClient.Received(1) .Enqueue<ISms>(Arg.Is<Expression<Func<ISms, Task>>>(expr => { // 校验表达式调用的是ISms的Send方法 if (expr.Body is not MethodCallExpression methodCall || methodCall.Method.Name != nameof(ISms.Send)) { return false; } // 提取Send方法传入的SmsContent参数 var actualContent = Expression.Lambda(methodCall.Arguments[0]) .Compile() .DynamicInvoke() as SmsContent; // 校验参数值和预期一致,如果你已经重写了SmsContent的Equals方法,可直接用actualContent.Equals(expectedSmsContent) return actualContent != null && actualContent.Phone == expectedSmsContent.Phone && actualContent.Text == expectedSmsContent.Text && actualContent.SendTime == expectedSmsContent.SendTime; }));
注意事项
- 如果你的
ISms.Send是同步无返回值方法,只需要把上面的Expression<Func<ISms, Task>>替换为Expression<Action<ISms>>即可。 - 如果需要多次用到类似校验,你可以把表达式解析和参数校验的逻辑封装为通用扩展方法,简化测试代码。
内容的提问来源于stack exchange,提问作者Mugurel
相关产品推荐
相关产品推荐

