Tuesday, July 31, 2007

Bagaimana nak test repository tanpa hit database?

Mock
Saya nak test repository object tapi tanpa perlu repository object tersebut melalui database bagaimana? Mock ?

Mock membolehkan saya test sesuatu object dengan beberapa expected return result. Sebagai contoh jika saya hendak find object User maka saya perlu dapatkan object User tersebut dari UserRepository, dan jika saya test UserRepository bersama dengan database, prosess test akan memakan masa yang agak lama kerana setiap test akan melalui prosess "Setup" dan "TearDown". Jadi apabila saya menggunakan mock object terhadap UserRepository, prosess interaction dengan database boleh diabaikan dan mock UserRepository boleh return expected result iaitu object User.

Dalam example code dibawah, saya hendak test ProspectServices dan didalm test tersebut saya perlu menggunakan ProspectRepository dan didalam real implementation ProspectRepository akan access DataAccessObject dan disini berlakunya communication dengan database. Untuk elakkan perkara itu berlaku maka saya akan mockkan ProspectRepository.

Selain dari itu saya juga bnyk menggunakan cara design by interface, dan cara ini sesuai digunakan dalam process test mock. Di mana kebanykkan code saya akan bermula dengan interface dan code implemantation hanya jika perlu.

Contoh code dibawah juga melibatkan 3 element penting interaction iaitu Presenter,Services dan Repository. Boleh dilihat bagaimana Presenter menggunakan Services untuk mendapatkan object Prospect dari Repository.


using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using Takaful.Core.Domain;
using Rhino.Mocks;
using Takaful.Core.Services;
using Takaful.Core.Repository;

namespace Services.TestStartProgramme
{
[TestFixture]
public class TestMockProspectServices
{
private MockRepository mock;
private Prospect prospect;

[SetUp]
public void InitSetup()
{
mock = new MockRepository();
prospect = new Prospect();
}

[TearDown]
public void TestCleanup()
{
mock.ReplayAll();
mock.VerifyAll();
}

[Test]
public void ShouldCreateProspect()
{

IProspectRepository iprospectRepository = mock.CreateMock<IProspectRepository>();

IProspectView view = mock.CreateMock<IProspectView>();

iprospectRepository.Save(prospect);

mock.ReplayAll();

ProspectServicesImpl services = new ProspectServicesImpl(iprospectRepository);

ProspectPresenterImpl presenter = new ProspectPresenterImpl(view, services);

presenter.SaveProspect(prospect);



}

[Test]
public void ShouldFindPropectById()
{

IProspectRepository iprospectRepository = mock.CreateMock<IProspectRepository>();

Expect.Call(iprospectRepository.GetDomainById("001")).Return(prospect);

ProspectServicesImpl psi = new ProspectServicesImpl(iprospectRepository);

mock.ReplayAll();

Assert.IsNotNull(psi.GetProspectById("001"));

}
}

public interface IProspectServices
{
void SaveProspect(Prospect prospect);
}

public class ProspectServicesImpl : IProspectServices
{
IProspectRepository iprospectRepository;

public ProspectServicesImpl(IProspectRepository iprospectRepository)
{
this.iprospectRepository = iprospectRepository;
}

public void SaveProspect(Prospect prospect)
{
iprospectRepository.Save(prospect);
}

public Prospect GetProspectById(string Id)
{
return iprospectRepository.GetDomainById(Id);
}
}

public interface IProspectPresenter
{

}

public interface IProspectView
{

}

public class ProspectPresenterImpl : IProspectPresenter
{
IProspectView pv;
IProspectServices ps;

public ProspectPresenterImpl(IProspectView pv, IProspectServices ps)
{
this.pv = pv;
this.ps = ps;
}

public void SaveProspect(Prospect prospect)
{
ps.SaveProspect(prospect);
}
}

public interface IProspectRepository : IRepository<Prospect, string>
{


}
}

0 comments: