Test

Test

Old forum URL: forums.lhotka.net/forums/t/5533.aspx


KJosh posted on Saturday, October 04, 2008

Hi,

Is there any example to know how to perform the unti test for business classes inheriting from CSLA base classes. In the unti test,

[Test]

public void TestGetProjects()

{

Project p = Project.GetProject();

Assert.IsTrue(p.Name == "Finance");

}

Could we call directly the business object method in the test or how we test the busienss object methods, fields? If we are able to call like the above(like Project.GetProject()), Then where we need to use the Mocking concept?

b) How we test the Busienss object derived from NameValueListBase?

Thanks in advance

JonStonecash replied on Sunday, October 05, 2008

This is an area that I have been exploring extensively in my blog: http://blog.magenic.com/blogs/jons/default.aspx.

This might be of help to you.

Jon Stonecash

FrankM replied on Monday, October 06, 2008

We use repository pattern to loose couple CSLA BO and DAL, and then use structuremap as the IOC container to inject the mock repository object for unit-testing CSLA BO.

nermin replied on Monday, October 06, 2008

Frank - are you using custom ObjectFactory implementation for injecting mock repository objects into Csla BO or?

I am really curios as - since the DP is instantiating CSLA BOs on the server, I found no better way to inject the Repository other than using custom ObjectFactory.

Or are you just using the 2 constructors scenario where the first - default is called by the DP, and second one accepts the IRepository<T> as a parameter, therefore alllowing injection and being the one used for testing (obviously default constructor calls the second one with the default repository as a parameter).

My last approach in separating the Repository from BO for tests was to use TypeMock, which does not need a reference to the Repository in order to mock it - no dependency injection (they use the Profiler API to inject Mock Repository at runtime directly into the running code).

I am looking for alternative approaches, so if you have an example please let us know.

FrankM replied on Monday, October 06, 2008

Actually I had tried the exact same "the custom constructor" way trying to inject the mock repository, but once I saw the the inject syntax provided by stuctureMap, thing becomes much easier. Here is the idea.

In your CSLA BO, use IOC container to get the repository instance,

        protected override void DataPortal_Fetch()
        {
           # Note: this objectfactory is in StructureMap namespace
            ICityRepository repostitory = ObjectFactory.GetInstance<ICityRepository>();
            ....data process...
        }

Then your unit-test can be easily done by create a mock repository and then inject into.
namespace Specs_for_CityBO
{

    [TestFixture]
    public class When_Fetching : ContextForBOTest
    {
        [Test]
        public void Should_get_one_BO_back_given_an_existing_id()
        {
           // Arrange
            _mockRepository.Stub(x => x.FindById(1)).Return(
                OneValidTestDTO );
           // Action
            var bo = CityBO.GetCityBO(1);
           // Assert
            Assert.That(bo.Name, Is.EqualTo("Mock city"));
        }

        [Test]
        [ExpectedException(typeof (DataPortalException))]
        public void Should_throw_exception_when_id_does_not_exist()
        {
            _mockRepository.Stub(x => x.FindById(-100)).Throw(new DataException("Data not found."));
            var bo = CityBO.GetCityBO(-100);
        }
    }
    public class ContextForBOTest
    {
        protected ICityRepository _mockRepository;

        [SetUp]
        public void Setup()
        {
            _mockRepository = MockRepository.GenerateStub<ICityRepository>();
            ObjectFactory.Inject(typeof(ICityRepository), _mockRepository);
        }

        [TearDown]
        public void TearDown()
        {
            // Assert
            _mockRepository.VerifyAllExpectations();

            ObjectFactory.Reset();
        }

        public CityDTO OneValidTestDTO
        {
            get
            {
                return new CityDTO
                           {
                               CityId = 1,
                               CityType = "City",
                               CountryId = 1,
                               Name = "Mock city",
                               ProvinceId = 1,
                           };
            }
        }

That's it. I was thinking to recommend Rocky don't use ObjectFactory term in the new version of CSLA.net. This won't be a problem but unitl structure Map became popular in CSLA community.

In the upcoming StructureMap 2.5, the above code can be a little bit shorter by using the build-in AutoMocker feature. http://devlicio.us/blogs/derik_whittaker/archive/2008/10/05/using-the-rhinoautomocker-that-is-part-of-structuremap-2-5.aspx

nermin replied on Monday, October 06, 2008

Thanks,

 

That is an excellent example J.  Very simple and elegant solution.  For some reason I did not think of putting StructureMap GetInstance call directly to the DP_XYZ(). 

 

 

From: FrankM [mailto:cslanet@lhotka.net]
Sent: Monday, October 06, 2008 4:31 PM
To: Nermin Dibek
Subject: Re: [CSLA .NET] Test

 

Actually I had tried the exact same "the custom constructor" way trying to inject the mock repository, but once I saw the the inject syntax provided by stuctureMap, thing becomes much easier. Here is the idea.

In your CSLA???BO, use IOC container to get the repository instance,

        protected override void DataPortal_Fetch()
        {
           #???Note: this objectfactory is in StructureMap namespace
            ICityRepository repostitory = ObjectFactory.GetInstance<ICityRepository>();
            ....data process...
        }

Then your unit-test can be easily done by create a mock repository and then inject into.

namespace Specs_for_CityBO
{

    [TestFixture]
    public class When_Fetching : ContextForBOTest
    {
        [Test]
        public void Should_get_one_BO_back_given_an_existing_id()
        {
           // Arrange
            _mockRepository.Stub(x => x.FindById(1)).Return(
                OneValidTestDTO );
           // Action
            var bo = CityBO.GetCityBO(1);
           // Assert
            Assert.That(bo.Name, Is.EqualTo("Mock city"));
        }

        [Test]
        [ExpectedException(typeof (DataPortalException))]
        public void Should_throw_exception_when_id_does_not_exist()
        {
            _mockRepository.Stub(x => x.FindById(-100)).Throw(new DataException("Data not found."));
            var bo = CityBO.GetCityBO(-100);
        }
    }
    public class ContextForBOTest
    {
        protected ICityRepository _mockRepository;

        [SetUp]
        public void Setup()
        {
            _mockRepository = MockRepository.GenerateStub<ICityRepository>();
            ObjectFactory.Inject(typeof(ICityRepository), _mockRepository);
        }

        [TearDown]
        public void TearDown()
        {
            // Assert
            _mockRepository.VerifyAllExpectations();

            ObjectFactory.Reset();
        }

        public CityDTO OneValidTestDTO
        {
            get
            {
                return new CityDTO
                           {
                               CityId = 1,
                               CityType = "City",
                               CountryId = 1,
                               Name = "Mock city",
                               ProvinceId = 1,
                           };
            }
        }


That's it. I was thinking to recommend Rocky don't use ObjectFactory term in the new version of CSLA.net. This won't be a problem but unitl structure Map became popular in CSLA community.

In the upcoming StructureMap 2.5, the above code can be a little bit shorter by using the build-in AutoMocker feature. http://devlicio.us/blogs/derik_whittaker/archive/2008/10/05/using-the-rhinoautomocker-that-is-part-of-structuremap-2-5.aspx



FrankM replied on Monday, October 06, 2008

We actually created a RepositoryManager in our CSLA BO, and put those GetInstance<>() code there. So the dataportal method is calling this RepositoryManger instead.

        private void DataPortal_Fetch(SingleCriteria<CityBO, int> criteria)
        {
          var data = RepositoryManager.CityRepository.FindById(criteria.Value);
...
        }

    public static class RepositoryManager
    {

        public static ICityRepository CityRepository
        {
            get{ return ObjectFactory.GetInstance<ICityRepository>();}
        }
This "wrapper" can allow us to easily switch to another IOC if that happens later.

 

KJosh replied on Monday, October 06, 2008

Hi,

What are repository patterns? and object factory patterns? How these are related to Tests? Could you provide me any links which will describe more about these concepts.

JonStonecash replied on Tuesday, October 07, 2008

A reference for the repository pattern:

http://martinfowler.com/eaaCatalog/repository.html

A couple of references for using the repository pattern with Linq:

http://iridescence.no/post/Linq-to-Sql-Programming-Against-an-Interface-and-the-Repository-Pattern.aspx

http://nixusg.com/post/2008/08/05/The-Automated-Testing-Continuum-Part-2-(Unit-Testing-LinQ).aspx

The ObjectFactory is a function of StructureMap.  StructureMap is an Inversion of Control (IOC) container that introduces a layer of in direction between the logic needing a dependent class/object and the dependent class/object.  StructureMap is but one of a number of IOC containers.  For a description of the IOC pattern see:

http://www.martinfowler.com/articles/injection.html

or

http://en.wikipedia.org/wiki/Inversion_of_control

As I said, there are a number of IOC packages:

StructureMap: http://structuremap.sourceforge.net/Default.htm

Unity: http://www.pnpguidance.net/Post/Unity10ReleasedMicrosoftIoCDependencyInjection.aspx

WinsorCastle: http://www.castleproject.org/container/index.html

And many more.

Jon Stonecash

 

twistedstream replied on Saturday, January 31, 2009

For those interested, I've put together a pretty straight-forward implementation of the Repository Pattern in CSLA.NET that uses dependency injection via Unity.  There are a couple blog posts that start here that cover my implementation and another more general blog post that explains the dependency injection technique it uses with CSLA.NET.

~pete

Copyright (c) Marimer LLC