Using StructureMap to mock DataAccess in CSLA BO

I had always thought StructureMap is just another IOC tool similar to Castle windsor, until yesterday I read Karl Seguin’s Foundations of Programming, Chapter 4, I was shocked immediately by the injectStub method provided by StructureMap, which is now renamed to inject(). I think this explicitly injection is better than TypeMock implicitly mock instance object.

For example, I have an Organization BO,


public static OrganizationBO GetOrganizationBO(int Id)
{
return DataPortal.Fetch<OrganizationBO>(new SingleCriteria<OrganizationBO, int>(Id));
}

private void DataPortal_Fetch(SingleCriteria<OrganizationBO, int> criteria)
{
OrganizationDTO data = DataAccess.OrganizationRepository().FindById(criteria.Value);

if (data != null)
{
LoadFromDTO(data);
}
}

The repository is declared in DataAccess class to centralize all the dataaccess coupling inside CALS BOs.


public static IRepository<OrganizationDTO> OrganizationRepository()
{

// instead of direct coupling return new OrganizationRepository();
// I use StrcutureMap
return ObjectFactory.GetInstance<IRepository<OrganizationDTO>>();
}

The content of IOC config file:

<DefaultInstance
PluginType=”DemoApp.Data.Interfaces.IRepository`1,DemoApp.Data”    PluggedType=”DemoApp.Data.Repository.OrganizationRepository,DemoApp.Data”
/>

We can also use other different ways to set dependency, like setDefault in code, or search assembly at  runtime as shown in this post.

Test  code:


[Test]
public void CanGetFromInjectedMockRepository()
{
var mockRepository = new Moq.Mock<IRepository<OrganizationDTO>>();

// Id in MoQ matters. But TypeMock doesn't care.
mockRepository.Expect(x => x.FindById(8172)).Returns(
new OrganizationDTO
{
Id = 1,
Name = "A test org name"
});

ObjectFactory.Inject(typeof(IRepository<OrganizationDTO>), mockRepository.Object);

var o = OrganizationBO.GetOrganizationBO(8172);

Assert.AreEqual(1, o.Id);
Assert.AreEqual("A test org name", o.Name);
}

Here is an artile introducing StructureMap, as it mentioned, StrucutreMap is very good choice if you are working on a class has no “constructor injection”, CSLA is one of those!

I have the same feeling, as the author Karl Seguin said, constructor injection doesn’t really solve the extensibility problem; how does someone add(try to replace) a new plug-in without recompiling the entire application?

The problem/drawback to DI is also obvious, the xml config file keeps growing and expanding. The performance and mantiance will become an issue. That’s why Boo was inverted to save / speed up Castle Windsor. But what about structure Map?

Also I need tool / method to test this xml config file, see details here and here. Unfortunately, I couldn’t make this <structuremap.verification> task loaded into NAnt, (maybe this doesn’t exist in those two dlls at all? I can’t tell because NAnt loadTask doesn’t have output). I tried to different folders and also “Forced scan” using <loadtasks> command, neither one works. Thanks God, Jeremy does have another way to test config file,so called smock test:

ObjectFactory.AssertConfigurationIsValid();

Regarding unit-test and mock, I spent a lot time trying to figure out how to reset the default back. It turns out the documented ObjectFactory.resetdefault has been changed to reset.

About these ads

Create multiple criteria to mock DataAcess in CSLABO

I posted before about using TypeMock to do mock data access in CSLABO. Today I am posting another way to mock dataaccess without using TypeMock.

First, I need to create IRepository<DTO> interface:

public interface IRepository<DTO>
{
DTO FindById(int id);
DTO Insert(DTO data);
void Update(DTO newData, DTO oldData);
void Delete(DTO data);
void DeleteById(int id);

Second, create my OrganizationRepository by implementing this IRepository<OrgarnizationDTO>.

Third, in my BO, add those 2 fetch methods:

private void DataPortal_Fetch(SingleCriteria<OrganizationBO, int> criteria)
{
DataPortal_Fetch(new RepositoryCriteria<OrganizationDTO>(new OrganizationRepository(), criteria));
}

private void DataPortal_Fetch(RepositoryCriteria<OrganizationDTO> repositoryCriteria)
{
var data = repositoryCriteria.Repository.FindById(
((SingleCriteria<OrganizationBO, int>)repositoryCriteria.Criteria).Value );

if (data != OrganizationDTO.NULL)
{
LoadFromDTO(data);
}
}

public class RepositoryCriteria<DTO>
{
public IRepository<DTO> Repository;
public CriteriaBase Criteria;

public RepositoryCriteria(IRepository<DTO> repository, CriteriaBase criteria)
{
Criteria = criteria;
Repository = repository;
}
}

Finally, The test code:

[Test]
public void CanFetchFromMoQRepository()
{
var mockRepository = new Moq.Mock<IRepository<OrganizationDTO>>();

// Id in MoQ matters. TypeMock doesn’t.
mockRepository.Expect(x => x.FindById(8172)).Returns(
new OrganizationDTO
{
Id = 1,
Name = “A test org name”
});

var o = DataPortal.Fetch<OrganizationBO>(
new RepositoryCriteria<OrganizationDTO>(
mockRepository.Object,
new SingleCriteria<OrganizationBO, int>(8172)
)
);

Assert.AreEqual(1, o.Id);
Assert.AreEqual(“A test org name”, o.Name);
}

The benefit of this solution is we are a little bit close to loose coupling, but later I figured out it’s still very hard to mock the Save() method. Had to back to TypeMock.

Set Property Expect setter in Moq

I have a piece of code like this, accept user login, if failed, set error message. simple enough, but when using Moq, I couldn’t figure out how to set the expectation of the returning error message at first.


        [Test]
        public void CanStopInValidLogin()
        {

            var mockedView = new Mock<ILoginView>();
            mockedView.Expect(x => x.UserName).Returns("invalid_user");
            mockedView.Expect(x => x.Password).Returns("invalid_password");
            string errmsg = "";

            mockedView.ExpectSet(x => x.ErrorMessage)
                .Callback( v => errmsg = v);

            _presenter = new LoginPresenter(mockedView.Object) { WindowsLoginMode = false };
            _presenter.DoLogin();

            // Can't use mockedView.Object to get property, because it's virtual(?)
            //Assert.AreEqual(LoginPresenter.LOGIN_FAILURE, mockedView.Object.ErrorMessage);

            // Should use callback to set the internal passing value to a outsider!?
            Assert.AreEqual(LoginPresenter.LOGIN_FAILURE, errmsg);

            Assert.IsEmpty( Csla.ApplicationContext.User.Identity.Name);
            Assert.IsEmpty(((AglcPrincipal)Csla.ApplicationContext.User).Identity.Roles);

        }

Not sure if this is the only way to make it, Moq seems very weird to mock properties setter.

Test Authorizatoin Rules in CSLA

To test CSLA BO’s authorization settings, I have to mock the IPrincipal.IsInRole method, RhinoMock example like this:

        [Test]
        [ExpectedException("System.Security.SecurityException")]
        public void CanHideForUnAuthorizedUser()
        {
            MockRepository mocks = new MockRepository();
            IPrincipal mockPrincipal = (IPrincipal)mocks.CreateMock<IPrincipal>();
            Csla.ApplicationContext.User = mockPrincipal;

            using (mocks.Record())
            {

                Expect.Call(mockPrincipal.IsInRole("user")).Return(false);

            }// Replay and validate interaction
            Order obj = null;
            using (mocks.Playback())
            {
                obj = Order.GetOrder(new Guid("c512e473-19fd-401c-80f6-055cf239e461"));

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

        }

         [Test]
        public void CanGetOrderUsingTypeMock()
        {

            // Setup Stud Data to be returned from mocked repository.
            // This code could be moved into record expectation block
            // but we assume everything inside that block is mocked.
            // to reduce confusion, just leave it here.
            // In fact , this mode is faster comparing the other one.
            OrderDTO stubOrderDTO = new OrderDTO();
            stubOrderDTO._OrderNumber = "12345";

            // Everything inside recorder block will be mocked.
            // expect the settng return value line: recorder.Return()
            using (RecordExpectations recorder = RecorderManager.StartRecording())
            {
                // Don't have to mock the IPricipal object "User"
                // Here TypeMock is too powerful. no need to think.
                Csla.ApplicationContext.User.IsInRole("user");
                recorder.Return(true);

                OrderRepository mockRepository = new OrderRepository();
                mockRepository.GetById(Guid.Empty);
                recorder.Return(stubOrderDTO);
            }

            Order p = Order.GetOrder(Guid.Empty);
            Assert.IsNotNull(p);
            Assert.AreEqual("12345", p.OrderNumber);
        }

After using typemock for a while, I suddenly tired of Rhino’s record-play syntax, looking into MoQ’s doc, it’s very similar to TypeMock, but it’s LinQ syntax (var and Lamba) are only available on 3.5 framework.

If using MoQ, the Rhino example will shorten to:


       [Test]
        [ExpectedException("System.Security.SecurityException")]
        public void CanHideForUnAuthorizedUser()
        {
            var mock = new Mock<IPrincipal>();
            mock.Expect(x => x.IsInRole("user")).Returns(true);
            Csla.ApplicationContext.User = mock;

            var obj = Order.GetOrder(new Guid("c512e473-19fd-401c-80f6-055cf239e461"));
        }