Building a Generic Repository

NOTE: This post is part of a series of posts for defining a repository. Please follow the table of contents for other related posts.

Table Of Contents

  1. Setting up the Solution

Setting up a basic test project

Okay, we have our basic interfaces defined. Now would be a good time to set up our test project.

In our previous post we added a test project to the our solution – Atl.Repository.Test. and also installed the following two packages –

PM> install-package xunit
PM> install-package xunit.runner.visualstudio

Yup, we are going to use xunit to run our test cases.

So far, we didn’t have any concrete domain implemented to write test cases. So, we are going to do it first. We will use a very simple domain entity, with one additional property.

We will try with complex domains later on. But for now let’s go with the easy one.

Our domain will be Organization and it looks like this –

namespace Atl.Repository.Domains.Organizations
{
    public class Organization : IDomain
    {
        public string Name { get; set; }

        #region IDomain Implementation

        public int Id { get; set; }
        public bool IsActive { get; set; }
        public bool IsDeleted { get; set; }
        public bool IsLocked { get; set; }
        public bool IsArchived { get; set; }
        public bool IsSuspended { get; set; }

        #endregion
    }
}

And yeah, it is as simple as it can get, with only one additional property – Name.

Okay, back to test project, we are going to write some test cases for CRUD operations with Organization.

Adding Populator

The purpose of a populator is providing us with test domains, models or simply POCO objects with predicable and human readable random values.

This step might seem unnecessary, but this is going to help us organize and test our repository in a very good way. For now, we only have one domain to test, but later on, we will have hundreds of domains to test or may be combinations of domains to test. We, are going to set up populators so that we will always get a predicable flow of test domains when we need them.

I am going to use Bogus for faking the domains, so let’s install Bogus –

PM> install-package bogus

Bogus is a simple and sane fake data generator for C# and .NET. If you are interested, you can get to know it here.

Even though we need populator for each domain, we are not going to provide populator that way. Instead, we are going to use a hierarchical populator structure, a composition of both Strategy & Decorator design pattern.

Read more about Strategy Pattern and Decorator Pattern.

Firstly, we define our populator interface 

namespace Atl.Repository.Test.Popoulators.Contracts
{
    public interface IPopulator where T: IDomain
    {
        T Populate();
        T Populate(T obj);
    }
}

So, our populator comes with two methods to populate an object. Now we add the base populator from which all other populator will be derived –

    public class BasePopulator : IPopulator where T: IDomain
    {
        public virtual T Populate()
        {
            var obj = Activator.CreateInstance<T>();
            return Populate(obj);
        }
        
        public virtual T Populate(T obj)
        {
            //populate common properties
            obj.IsActive = true;
            obj.IsDeleted = false;
            obj.IsArchived = false;
            obj.IsLocked = false;
            obj.IsSuspended = false;

            return obj;
        }
    }

Finally we add the customized populator that only deals with Organization –

 public class OrganizationPopulator : BasePopulator
    {
        public override Organization Populate()
        {
            var fakeOrg = new Faker()
                .RuleFor(x => x.Name, f => f.PickRandom(new string[] {"Apple", "Microsoft", "Atlassian"}));

            return base.Populate(fakeOrg.Generate());
        }

        
        public override Organization Populate(Organization obj)
        {
            //populate baase properties
            return base.Populate(obj);
        }
    }

basically, what we did here is –

  1. Have overridden the populate method to put our own values for the Name property
  2. Told bogus, to create a new Faker to create an Organization object, with any of these names – “Apple”, “Microsoft”, “Atlassian”.
  3. Created the faked object and passed it to the base populator, to populate the common properties and return the object.

In the end, we have a randomly generated object but with predicable name. That is the purpose of a populator.

Testing the Populator

Now lets test our newly created populator, to make sure the it is generating the values as expected. We are going the add a test method to test out populator to see if the generated name falls into our defined range i.e. “Apple”, “Microsoft”, “Atlassian” –

Xunit, has a great option to inject classes at test time. I am going to use that feature and inject the poplator. You can read more about ClassFixture here.

    public class WriteRepositoryTest : IClassFixture
    {
        private readonly OrganizationPopulator _organizationPopulator;

        public WriteRepositoryTest(OrganizationPopulator organizationPopulator)
        {
            _organizationPopulator = organizationPopulator;
        }

        [Fact]
        public void GenerateOrganization()
        {
            var org = _organizationPopulator.Populate();

            Assert.True(new string[] {"Apple", "Microsoft", "Atlassian"}.Contains(org.Name), "Didn't generate expected organization.");
        }

        [Fact]
        public void CreateSimpleObject()
        {

        }
    }

Now we run the test using the integrated test explorer and Voila! Passed.

2017-08-13_9-31-55

By this time the test project looks like this  (the test class not shown) –

2017-08-13_9-33-28

(to be continued….)

Advertisements

About Mahmudul Islam

Senior Software Engineer Sitback Solutions (https://www.sitback.com.au/)
This entry was posted in ADO.Net Entity Framework, C# .Net, Uncategorized. Bookmark the permalink.

One Response to Building a Generic Repository

  1. Pingback: Building a Generic Repository using Repository Pattern – Heart of a Brainless Coder

I would like to say something ...

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