在.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);
}