Moq在.net中比较出名的mock框架,NSubstitute也是属于这类框架,使用方式也如出一辙,是通过实现子类来达到mock的效果。下面的测试方法都是按照 UnitTest的三板斧Arrange Act Assert来展开的,代码具体如下。
using Microsoft.VisualBasic; using NSubstitute; using NSubstitute.ExceptionExtensions; using System; using System.Threading.Tasks; using Xunit; namespace NSubstituteUnitTest { public class UserManageUnitTest { IUserService _userService; UserManage _userManage; public UserManageUnitTest() { //mock接口 _userService = Substitute.For<IUserService>(); _userManage = new UserManage(_userService); } [Fact] public async Task AddUser_Default_Return() { var user = new User { UserName = "a", Password = "b" }; //mock方法的返回值 _userService.AddUserAsync(Arg.Any<User>()).Returns(true); var result = await _userManage.AddUserAsync(user); Assert.Equal(true, result); } [Fact] public async Task AddUser_ServiceError_ReturnFalse() { var user = new User { UserName = "a", Password = "b" }; //mock方法的返回值 _userService.AddUserAsync(Arg.Any<User>()).Returns(false); var result = await _userManage.AddUserAsync(user); Assert.Equal(false, result); } [Fact] public async Task AddUser_Exception_ReturnFalse() { var user = new User { UserName = "a", Password = "b" }; //mock方法发生异常 _userService.AddUserAsync(Arg.Any<User>()).Throws(new Exception("异常")); var result = await _userManage.AddUserAsync(user); Assert.Equal(false, result); } [Theory] [InlineData("", "a")] [InlineData("a", "")] [InlineData("", "")] [InlineData(null, "a")] [InlineData("a", null)] [InlineData(null, null)] [InlineData(" ", "a")] [InlineData("a", " ")] [InlineData(" ", " ")] public async Task AddUser_IsNullOrEmpty_ReturnFalse(string userName, string password) { //这个逻辑没有设用到接口,所以不需要mock var user = new User { UserName = userName, Password = password }; var result = await _userManage.AddUserAsync(user); Assert.Equal(false, result); } } //被测试的类 public class UserManage { private readonly IUserService _userService; public UserManage(IUserService userService) { _userService = userService; } public async Task<bool> AddUserAsync(User user) { try { if (!string.IsNullOrEmpty(user.UserName.Trim()) && !string.IsNullOrEmpty(user.Password.Trim())) { return await _userService.AddUserAsync(user); } else { return false; } } catch { return false; } } } //接口 public interface IUserService { Task<bool> AddUserAsync(User user); } //实体 public class User { public string UserName { get; set; } public string Password { get; set; } } }
单元测试结果
覆盖率结果
更复杂的调用参看官方文档:https://nsubstitute.github.io/help/getting-started/
想要更快更方便的了解相关知识,可以关注微信公众号