Mock dbcontext

在.net 程序里面,我们最常用的ORM库就是entity framework.

在.net core之后, Entity farmework core就支持 Memory的模式了。

所以我们可以方便的使用这个来进行单元测试了。 缺陷就是一直用原生sql的语句是没有办法进行单元测试的 假设我们有如下的一个DbContext和Student和StudentService EFcore 需要使用Nuget把Microsoft.EntityFrameworkCore包加入到项目中

using System;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace MyFirstUnitTests
{
    public class Student
    {
        public int Id { get; set; }
        public DateTime Birthday { get; set; }
        public string Name { get; set; }
    }

    public class MalemaDbContext : DbContext
    {
        public MalemaDbContext(DbContextOptions<MalemaDbContext> options) 
            : base(options)
        {
        }
        public DbSet<Student> Students { get; set; }
    }

    public class StudentService
    {
        private readonly MalemaDbContext malemaDbContext;

        public StudentService(MalemaDbContext malemaDbContext)
        {
            this.malemaDbContext = malemaDbContext;
        }

        //这个方法使用 DbContext将Student添加到数据库
        public async Task Add(Student student)
        {
            malemaDbContext.Add(student);
            await malemaDbContext.SaveChangesAsync();
        }
    }
}

首先我们需要使用Nuget 将 Microsoft.EntityFrameworkCore.InMemory包加入到我们的测试项目当中 接下来我们创建一个DbContextHelper,用来获取 memory的dbcontext

public static class DbContextHelper
{
    public static MalemaDbContext GetMemory(string name = null)
    {
        var builder = new DbContextOptionsBuilder<MalemaDbContext>();
        if (name == null)
        {
            name = Guid.NewGuid().ToString();
        }

        builder.UseInMemoryDatabase(name);
        return new MalemaDbContext(builder.Options);
    }

    public static (MalemaDbContext, Func<MalemaDbContext>) Get(params object[] parms)
    {
        var builder = new DbContextOptionsBuilder<MalemaDbContext>();
        var name = Guid.NewGuid().ToString();
        builder.UseInMemoryDatabase(name);
        var context = new MalemaDbContext(builder.Options);
        if (parms.Count() > 0)
        {
            context.AddRange(parms);
            context.SaveChanges();
        }

        var func = new Func<MalemaDbContext>(() =>
        {
            return new MalemaDbContext(builder.Options);
        });
        return (context, func);
    }
}

最后我们就可以测我们的单元测试了

[Fact]
public async Task Add_Should_Add_Entity_Into_Db()
{
    var (db, dbFunc) = DbContextHelper.Get();
    var service = new StudentService(db);
    var student = new Student()
    {
        Id = 1,
        Birthday = DateTime.Now,
        Name = "test1"
    };
    await service.Add(student);

//这边要用一个新的dbContext才表明student真的是有被插入到数据库了
    dbFunc().Students.Count().Should().Be(1);
    dbFunc().Students.FirstOrDefault().Should().BeEquivalentTo(student);
}
上一篇:参数捕获器
下一篇:Mock Ilogger
最近更新的
...