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/
想要更快更方便的了解相关知识,可以关注微信公众号