TypeMock Repository object in CSLA BO

CSLAEx DAL’s basic idea is adding an middle method in DataPortal_XXX():

CSLA BO Get -> DataPortal_Fetch -> DataAccess.ReadDataMethod (return SafeDataReader)

I added another repository in between to introduce stong type domain object instead of DataReader (I think DataReader is not much difference than DataSet in UI)

CSLA BO Get -> DataPortal_Fetch ->Repository.DataProssingMethod() (return DTO)-> DataAccess.ReadDataMethod (return SafeDataReader)

Repository can be mocked, and DataAccess can be tested (based on peeking into db then writing assert expection.)

The next problem is, how to test / mock the top level static Get method? I tried using adapter pattern by adding a injectable public constructor to BO, then the test case code like this:

[Test]
public void GetProductOnBOTestUsingMock()
{
MockRepository mocks = new MockRepository();
IProductRepository mockRepository = (IProductRepository)mocks.CreateMock<IProductRepository>();
Product p = new Product(mockRepository);
Guid id = Guid.NewGuid();
using (mocks.Record())
{
ProductDTO fakeProduct = null;
Expect.Call(mockRepository.GetById(id)).Return(fakeProduct);

}// Replay and validate interaction
Product obj = null;
using (mocks.Playback())
{
obj = p.GetProductAdaptor(id);

}// Post-interaction assertions
Assert.IsNull(obj);

Assert.AreEqual(obj.ProductName, "");
}

This test case failed, because in CSLA’s calling sequence:

Client.DataPortal -> LocalProxy -> Server.DataPortal -> 1. ServicedDataPortal TransactionalTypes.EnterpriseServices: 2. TransactionalTypes TransactionalTypes.TransactionScope 3. SimpleDataPortal default

The last step will run this piece of code:

namespace Csla.Server
{

public class SimpleDataPortal : IDataPortalServer
{
public DataPortalResult Fetch(Type objectType, object criteria, DataPortalContext context)
{
object obj = null;
try
{
// create an instance of the business object.
obj = Activator.CreateInstance(objectType, true);
...

My attempt to adding constuctor injection won’t suceed. I had to back to TypeMock then:

[Test]
public void TestGetUsingTypeMock()
{
// Setup Stud Data
ProductDTO stubProdDTO = new ProductDTO();
stubProdDTO.ProductName = "TypeMocked prod name";

// Everything inside recorder block will be mocked.
// expect the last line settng return value.
using (RecordExpectations recorder = RecorderManager.StartRecording())
{
ProductRepository mockRepository = new ProductRepository();
mockRepository.GetById(Guid.Empty);
recorder.Return(stubProdDTO);
}

Product p = Product.GetProduct(Guid.Empty);
Assert.IsNotNull(p);
Assert.AreEqual("TypeMocked prod name", p.ProductName);
}

It’s green

Another benefit to add a repository between BO and DataAccess object might be, it will be easier to use Castle’s IIntercepter to log those repository calls. As Castle warned:

If you are registering a component without an interface (the service) then only virtual methods can be intercepted.

Miguel seems doesn’t like code against interface in his dataaccess class, neither does Rocky in his CSLA BO. But we can add interface in our repository object. I am going to post this part of code once I finish it.

About repository class, JP treats those classes as DataAccess objects which makes sense, the return type of his repository class is Domain object, so he convert those domain object to DTO in his task layer using mapper class (Martin Fowler initially uses XXXAssembly class to do the conversion between domain object and DTO) Our CSLA BO is too rich which can not be returned from repository, so my repository just returns DTO instead. I think this solution can eliminate the usage of task and mapper object in my project.

Advertisements

2 thoughts on “TypeMock Repository object in CSLA BO

  1. Pingback: Another way to mock DataAcess in CSLABO « maonet technotes

  2. Pingback: Using StructureMap to mock DataAccess in CSLA BO « maonet technotes

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s