用NSubstitute来mock

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用NSubstitute来mock相关的知识,希望对你有一定的参考价值。

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/

以上是关于用NSubstitute来mock的主要内容,如果未能解决你的问题,请参考以下文章

测试篇——初探单元测试

参数匹配不能与 NSubstitute 一起正常工作

使用 NSubstitute 模拟出现问题时抛出异常的方法

单元测试-隔离框架NSubstitute

NSubstitute DbSet / IQueryable<T>

NSubstitute ForPartsOf模拟除一个以外的所有方法?