Entity Framework사용 시 편리한 테스트 방법
Entity Framework를 통해 DB 컨트롤을 하는 객체를 만들었을 때 Mock을 통해 쉽게 테스트를 할 수 있는 프레임웍을 소개 하고자 한다. rowanmiller가 GitHub에 올려둔 "EntityFramework.Testing"를 살펴 보면 간단한 사용 방법을 보여주고 있다. 아래 코드는 테스트 부분만 따로 떼어내서 간단한 부연 설명을 주석으로 추가 하였다.
var data = new List<Blog> { new Blog{ Name = "BBB" }, new Blog{ Name = "CCC" }, new Blog{ Name = "AAA" } };
[코드1] 데이터 원본
'코드1'에서와 같은 데이터에서 Mock을 통해 DBContext를 만들기 위해서는 '코드2' 에서와 같이 해줘야 했으나 "EntityFramework.Testing"를 사용하면 "코드3"와 같은 코드로 대체할 수 있다.
var mockSet = new Mock<DbSet<Blog>>(); mockSet.As<IQueryable<Blog>>().Setup(m =>m.Provider).Returns(data.Provider); mockSet.As<IQueryable<Blog>>().Setup(m =>m.Expression).Returns(data.Expression); mockSet.As<IQueryable<Blog>>().Setup(m =>m.ElementType).Returns(data.ElementType); mockSet.As<IQueryable<Blog>>().Setup(m =>m.GetEnumerator()).Returns(data.GetEnumerator()); var mockContext = new Mock<BloggingContext>(); mockContext.Setup(c => c.Blogs).Returns(mockSet.Object);
[코드2] 기존 초기화 코드
var set = new MockDbSet<Blog>() .SetupSeedData(data) .SetupLinq();
[코드3] 변경된 초기화 코드
테스트 및 직접 확인할 수 있는 코드를 '코드4~6'를 통해 직접 확인해 보기를 바란다.
public class BloggingContext : DbContext { public virtual DbSet<Blog> Blogs { get; set; } public virtual DbSet<Post> Posts { get; set; } } public class Blog { public int BlogId { get; set; } public string Name { get; set; } public string Url { get; set; } public virtual List<Post> Posts { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } public int BlogId { get; set; } public virtual Blog Blog { get; set; } }
[코드4] 기본 Entity 클래스 선언
public class BlogsController : Controller { private readonly BloggingContext db; public BlogsController(BloggingContext context) { db = context; } public async Task<ViewResult> Index() { var query = db.Blogs.OrderBy(b => b.Name); return View(await query.ToListAsync()); } }
[코드5] 테스트할 클래스 생성
// https://github.com/rowanmiller/EntityFramework.Testing/wiki [TestClass] public class EntityFrameworkTest { [TestMethod] public async Task Index_returns_blogs_ordered_by_name() { // 테스트 데이터 생성 - Arrange var data = new List<Blog> { new Blog{ Name = "BBB" }, new Blog{ Name = "CCC" }, new Blog{ Name = "AAA" } }; // Mock를 통해 Context 세팅 -- Act // Mock객체가 반환할 객체 단위를 List<Blog>에서 가져오도록 세팅한 것이다. var mockSet = new MockDbSet<Blog>() .SetupSeedData(data) .SetupLinq();
// 기존 초기화 세팅 //var mockSet = new Mock<DbSet<Blog>>(); //mockSet.As<IQueryable<Blog>>().Setup(m => m.Provider).Returns(data.Provider); //mockSet.As<IQueryable<Blog>>().Setup(m => m.Expression).Returns(data.Expression); //mockSet.As<IQueryable<Blog>>().Setup(m => m.ElementType).Returns(data.ElementType); //mockSet.As<IQueryable<Blog>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());
var context = new Mock<BloggingContext>(); context.Setup(c => c.Blogs).Returns(mockSet.Object); // BlogsController 의 Index를 실행 var controller = new BlogsController(context.Object); var result = await controller.Index(); // 결과값 확인 - Assert var blogs = (List<Blog>)result.Model; Assert.AreEqual(3, blogs.Count()); Assert.AreEqual("AAA", blogs[0].Name); Assert.AreEqual("BBB", blogs[1].Name); Assert.AreEqual("CCC", blogs[2].Name); } }
[코드6] 테스트 코드
'.Net Framework' 카테고리의 다른 글
Windows Service에서 디비깅을 쉽게 하는 방법 (0) | 2015.10.13 |
---|---|
Visual Studio "14" CTP Now Available - Visual Studio 2014 (0) | 2014.06.09 |
A C# 6.0 Language Preview (0) | 2014.05.23 |
C#에서 Enum 타입을 다중값으로 활용 - Flags Attribute (0) | 2014.05.21 |
인터넷에서 프로그래밍 정보 얻는 사이트 - 영어 사이트 (0) | 2014.01.06 |