Entity Framework사용 시 편리한 테스트 방법


참조 URL
  1. http://msdn.microsoft.com/en-US/data/dn314429
  2. https://github.com/rowanmiller/EntityFramework.Testing/wiki
  3. 페이스 북의 "Gyuwon Yi"님이 소개를 해줘서 알게된 프레임워크

 


 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 { getset; }
    public virtual DbSet<Post> Posts { getset; }
}
 
public class Blog
{
    public int BlogId { getset; }
    public string Name { getset; }
    public string Url { getset; }
 
    public virtual List<Post> Posts { getset; }
}
 
public class Post
{
    public int PostId { getset; }
    public string Title { getset; }
    public string Content { getset; }
 
    public int BlogId { getset; }
    public virtual Blog Blog { getset; }
}

[코드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] 테스트 코드








+ Recent posts