在寫單元測試時,難免都會遇到 DbContext 的相依,在 ASP.NET Core 裡面什麼服務都是走DI,也包含了DbContext,這讓替換 DbContext 變得更容易了
在寫單元測試時,難免都會遇到 DbContext 的相依,在 ASP.NET Core 裡面什麼服務都是走DI,也包含了DbContext,這讓替換 DbContext 變得更容易了
準備簡單的待測試邏輯,並且使用SqlServer
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.5"/>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.5"/>
public class MemberService
{
private readonly ITestDbContext _dbContext;
public MemberService(ITestDbContext dbContext)
{
_dbContext = dbContext;
}
public bool MemberIsExists(string id)
{
var member = _dbContext.Member.FirstOrDefault(r => r.Id == id);
return member != null;
}
}
public class TestDbContext : DbContext, ITestDbContext
{
public TestDbContext(DbContextOptions<TestDbContext> options)
: base(options)
{
}
public DbSet<Member> Member { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
}
}
在測試裡就可以透過 TestDbContext 的參數 DbContextOptions<TestDbContext> 來建立測試用的DB,並注入 Service,在測試我改用 InMemoryDb(看個人需求也可以用Sqlite)
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="3.1.5" />
public class UnitTest1
{
private readonly TestDbContext _testDbContext;
private readonly MemberService _memberService;
public UnitTest1()
{
var dbContextOptions = new DbContextOptionsBuilder<TestDbContext>()
.UseInMemoryDatabase(Guid.NewGuid().ToString("N"))
.Options;
_testDbContext = new TestDbContext(dbContextOptions);
_memberService = new MemberService(_testDbContext);
}
[Fact]
public void Is()
{
_testDbContext.Member.Add(new Member()
{
Id = "id"
});
_testDbContext.SaveChanges();
var isExists = _memberService.MemberIsExists("id");
Assert.True(isExists);
}
[Fact]
public void Not()
{
var isExists = _memberService.MemberIsExists("id");
Assert.False(isExists);
}
}
接著簡單的測試就誕生了,可以依照自己的需求替換DB,或是準備當次測試需要的資料
SampleCode https://github.com/ianChen806/UnitTestDbSample
在寫單元測試時,難免都會遇到 DbContext 的相依,在 ASP.NET Core 裡面什麼服務都是走DI,也包含了DbContext,這讓替換 DbContext 變得更容易了
準備簡單的待測試邏輯,並且使用SqlServer
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.5"/> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.5"/>
public class MemberService { private readonly ITestDbContext _dbContext; public MemberService(ITestDbContext dbContext) { _dbContext = dbContext; } public bool MemberIsExists(string id) { var member = _dbContext.Member.FirstOrDefault(r => r.Id == id); return member != null; } } public class TestDbContext : DbContext, ITestDbContext { public TestDbContext(DbContextOptions<TestDbContext> options) : base(options) { } public DbSet<Member> Member { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { } }
在測試裡就可以透過 TestDbContext 的參數 DbContextOptions<TestDbContext> 來建立測試用的DB,並注入 Service,在測試我改用 InMemoryDb(看個人需求也可以用Sqlite)
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="3.1.5" />
public class UnitTest1 { private readonly TestDbContext _testDbContext; private readonly MemberService _memberService; public UnitTest1() { var dbContextOptions = new DbContextOptionsBuilder<TestDbContext>() .UseInMemoryDatabase(Guid.NewGuid().ToString("N")) .Options; _testDbContext = new TestDbContext(dbContextOptions); _memberService = new MemberService(_testDbContext); } [Fact] public void Is() { _testDbContext.Member.Add(new Member() { Id = "id" }); _testDbContext.SaveChanges(); var isExists = _memberService.MemberIsExists("id"); Assert.True(isExists); } [Fact] public void Not() { var isExists = _memberService.MemberIsExists("id"); Assert.False(isExists); } }
接著簡單的測試就誕生了,可以依照自己的需求替換DB,或是準備當次測試需要的資料
SampleCode https://github.com/ianChen806/UnitTestDbSample