Mocking Database Context In Repository Unit Test Using Effort

Seringkali kita ingin membuat unit test di level repository untuk menguji query yang kita buat pada sebuah repository. Karena pada unit testing, prinsipnya adalah melakukan isolasi dari external class ataupun external resource dan eksekusi unit testing harus bisa secepat mungkin, maka kita hindari menggunakan database secara langsung.

Jika menggunakan database secara langsung, sangat berpengaruh pada kecepatan eksekusi unit testing dan masalah data yang harus diinsert dan dihapus ketika selesai digunakan oleh unit testing. Salah satu solusinya adalah menggunakan in-memory-database. In-memory database ini akan dihancurkan oleh Garbage collector ketika sudah tidak digunakan.

Untuk mempermudah kita bisa menggunakan Effort. Instalasi cukup mudah, cukup di install lewat nuget package manager.

Pada initialisasi unit test kita mockup context kita.

Pertama, buat connection untuk Effort.

var connection = DbConnectionFactory.CreateTransient();

Selanjutnya pada class context, kita tambahkan satu constuctor untuk melewatkan connection dari Effort tersebut.

public BookStoreEntities(DbConnection connection) : base(connection, true)
{
}

pada unit test initialization method lewatkan connection Effort tadi ke context dan tambahkan code untuk membuat database jika tidak ada. Ini untuk menghindari munculnya error migrations data nantinya.

_context = new BookStoreEntities(connection);
_context.Database.CreateIfNotExists();

selanjutnya, insert data untuk table table yang akan kita gunakan nantinya.

_context.Categories.Add(new Category { Name = "Programming" });
_context.SaveChanges();
var category = _context.Categories.First();
_context.Books.Add(new Book { Title="Effort In Action", Category = category });
_context.Books.Add(new Book { Title = "C# In Action", Category = category });
_context.SaveChanges();

Kode program selengkapnya seperti ini.

[TestClass]
public class BookRepositoryTest
{
private BookStoreEntities _context;
private IUnitOfWork _unitOfWork;
private IGenericRepository _bookRepository;
[TestInitialize]
public void Setup()
{

var connection = DbConnectionFactory.CreateTransient();
_context = new BookStoreEntities(connection);
_context.Database.CreateIfNotExists();

_context.Categories.Add(new Category { Name = "Programming" });
_context.SaveChanges();
var category = _context.Categories.First();
_context.Books.Add(new Book { Title="Effort In Action", Category = category });
_context.SaveChanges();
_unitOfWork = new EFUnitOfWork(_context);
_bookRepository = _unitOfWork.GetGenericRepository();
}
[TestCleanup]
public void Cleanup()
{
_context = null;
_unitOfWork = null;
_bookRepository = null;
}
[TestMethod]
public void GetAll()
{
var books = _bookRepository.Get().ToList();
Assert.AreNotEqual(0, books.Count);
}
}

[TestMethod]
public void FindByName()
{
var books = _bookRepository.Get(x=>x.Title.Contains("Effor")).ToList();
Assert.AreNotEqual(0, books.Count);
}
[TestMethod]
public void GetById()
{
var book = _bookRepository.GetById(1);
Assert.IsNotNull(book);
}

Jika unit Test kita jalankan hasilnya seperti ini.

unit-test-effort

 

Selamat mencoba!

Iklan

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout /  Ubah )

Foto Google

You are commenting using your Google account. Logout /  Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout /  Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout /  Ubah )

Connecting to %s