zoukankan      html  css  js  c++  java
  • .NET Core之单元测试(三):Mock框架Moq的使用

    编写一个API

    新增一个接口

    public interface IFoo
    {
        bool Ping(string ip);
    }
    

    接口实现

    public class Foo : IFoo
    {
        public bool Ping(string ip)
        {
            return new Random().Next(1, 100) % 2 == 1;
        }
    }
    

    编写一个待测试的API,其中有三个依赖项:SqliteDbContextILogger<SampleController>IFoo
    API实现的功能:先获取SqliteDbContext中的SampleEntity,如果其中的属性StringValue值为ping,并且结果为False,则返回404,否则返回SampleEntity

    [Route("api/[controller]")]
    [ApiController]
    public class SampleController : ControllerBase
    {
        private readonly SqliteDbContext _sqliteDbContext;
        private readonly ILogger<SampleController> _logger;
        private readonly IFoo _foo;
        public SampleController(SqliteDbContext sqliteDbContext, ILogger<SampleController> logger,IFoo foo)
        {
            _logger = logger;
            _foo = foo;
            _sqliteDbContext = sqliteDbContext;
        }
        [HttpGet("{id}")]
        public async Task<IActionResult> Get(int id)
        {
            var sampleData = await _sqliteDbContext.SampleEntity
                .SingleOrDefaultAsync(s => s.Id == id);
            if (sampleData?.StringValue == "ping")
            {
                var pingOk = _foo.Ping("localhost");
                if (!pingOk)
                    return NotFound();
            }
            return Ok(sampleData);
        }
    }
    

    测试用例

    • Mock ILogger<SampleController>
    var loggerMock = new Mock<ILogger<SampleController>>();
    var logger = loggerMock.Object;
    
    • Mock Ping(string ip)
    var fooMock = new Mock<IFoo>();
    fooMock.Setup(foo => foo.Ping("localhost")).Returns(true);
    var foo = fooMock.Object;
    

    关于Moq的更多操作可参见:Moq4 Quickstart

    • 修改GetSqliteDbContextAsync(),新增一个ID为2的数据记录
    private async Task<SqliteDbContext> GetSqliteDbContextAsync()
    {
        var options = new DbContextOptionsBuilder<SqliteDbContext>()
            .UseInMemoryDatabase(Guid.NewGuid().ToString())
            .Options;
        var sqliteDbContext = new SqliteDbContext(options);
        sqliteDbContext.SampleEntity.Add(new Infrastructure.Entities.SampleEntity
        {
            Id = 1,
            BoolValue = false,
            DateTimeValue = DateTime.Now,
            StringValue = "sample"
        });
    
        sqliteDbContext.SampleEntity.Add(new Infrastructure.Entities.SampleEntity
        {
            Id = 2,
            BoolValue = false,
            DateTimeValue = DateTime.Now,
            StringValue = "ping"
        });
        await sqliteDbContext.SaveChangesAsync();
        return sqliteDbContext;
    }
    
    • 测试Ping==True
    [TestMethod]
    public async Task Get_ReturnOK_WithPingTrue()
    {
        // Arrange
        var dbContext = await GetSqliteDbContextAsync();
    
        var loggerMock = new Mock<ILogger<SampleController>>();
        var logger = loggerMock.Object;
    
        var fooMock = new Mock<IFoo>();
        fooMock.Setup(foo => foo.Ping("localhost")).Returns(true);
        var foo = fooMock.Object;
    
        var controller = new SampleController(dbContext, logger, foo);
    
        // Act
        var response = await controller.Get(2);
        var responseModel = ((OkObjectResult)response).Value as SampleEntity;
    
        // Assert
        Assert.IsInstanceOfType(response, typeof(OkObjectResult));
        Assert.IsTrue(responseModel.Id == 2);
        Assert.IsFalse(responseModel.BoolValue);
        Assert.IsTrue(responseModel.StringValue == "ping");
    }
    
    • 测试Ping==False
    [TestMethod]
    public async Task Get_ReturnOK_WithPingFalse()
    {
        // Arrange
        var dbContext = await GetSqliteDbContextAsync();
    
        var loggerMock = new Mock<ILogger<SampleController>>();
        var logger = loggerMock.Object;
    
        var fooMock = new Mock<IFoo>();
        fooMock.Setup(foo => foo.Ping("localhost")).Returns(false);
        var foo = fooMock.Object;
    
        var controller = new SampleController(dbContext, logger, foo);
    
        // Act
        var response = await controller.Get(2);
    
        // Assert
        Assert.IsInstanceOfType(response, typeof(NotFoundResult));
    }
    
    • 测试结果
      在这里插入图片描述
  • 相关阅读:
    git(1)-git关联GitHub-windows-转载
    jenkins(4)-jenkins配置邮件通知
    jenkins(3)-linux下安装jenkins(yum install方式)
    【PAT甲级】1090 Highest Price in Supply Chain (25 分)(DFS)
    【PAT甲级】1087 All Roads Lead to Rome (30 分)(MAP【int,string】,邻接表,DFS,模拟,SPFA)
    【PAT甲级】1018 Public Bike Management (30 分)(DFS,SPFA)
    Educational Codeforces Round 61 (Rated for Div. 2) G(线段树,单调栈)
    Atcoder Grand Contest 032C(欧拉回路,DFS判环)
    Educational Codeforces Round 62 (Rated for Div. 2)E(染色DP,构造,思维,组合数学)
    Atcoder Grand Contest 031C(构造,思维,异或,DFS)
  • 原文地址:https://www.cnblogs.com/zhaobingwang/p/12354045.html
Copyright © 2011-2022 走看看