Friday, June 18, 2010

Generate Sequences and Random data using NBuilder

Background

In mu earlier post on how to use NBuilder to generate test data, I had demonstrated few basic features of NBuilder. I had also mentioned that I will be doing a follow up post on other features that this dll provides. In this post I’ll be demonstrating the sequencing and random pick list features. I’ll be reusing the classes from the previous post.

How to use NBuilder to generate Sequence data

In our PersonEntity class we have the Id property. Assume that we have an requirement to use the running serial number for this property. Since our PersonRepository will be returning a list when we call the GetAll method, we can apply the sequencing logic in this method.

NBuilder has a notion of SequentialGenerator. This is similar to setting an identitty column in the database schema. We can specify the increment and the direction to the constructor of this class. We can also set the initial value from where we would like to start the sequence.

[TestMethod()]
        public void GetAllTest_ShouldReturn_SequntialPersonIds()
        {
            SequentialGenerator<int> sequenceGenerator = new SequentialGenerator<int> { Direction = GeneratorDirection.Ascending, Increment = 1 };

            const int numberOfPersons = 10;

            IList<PersonEntity> persons = Builder<PersonEntity>.CreateListOfSize(numberOfPersons)
                .WhereAll().Have(x => x.Id = sequenceGenerator.Generate())
                .Build();

            personRepository.Persons = persons.ToList();

            IList<PersonEntity> result = personRepository.GetAll();

            Assert.AreEqual(numberOfPersons, result.Count, "Expected and actual count is not same");
            Assert.AreEqual(result[0].Id, 1);
        }


As can be seen from the above code snippet, I have set the direction as Ascending and the increment as 1. I have also set the Id property to be the sequence number generated from Generate() method. If you run this test, it fails. I was assuming that the first item in the collection will have the Id as 1. But my assumption was wrong.



Please note that we need to set the starting value before we can all the Generate method.



sequenceGenerator.StartingWith(1);


On rerunning the test, it passes successfully.



How to use NBuilder to generate Random data



Assume that the functionality is the reverse of what was implemented above. Now we need to use random numbers instead of a sequence. NBuilder again comes to the rescue. Take a look at the following code snippet



[TestMethod()]
        public void GetAllTest_ShouldReturn_RandomPersonIds()
        {
            RandomGenerator randomGenerator = new RandomGenerator();

            const int minimumId = 5;
            const int maximumId = 50;
            const int numberOfPersons = 10;

            IList<PersonEntity> persons = Builder<PersonEntity>.CreateListOfSize(numberOfPersons)
                .WhereAll().Have(x => x.Id = randomGenerator.Next(minimumId, maximumId))
                .Build();

            personRepository.Persons = persons.ToList();

            IList<PersonEntity> result = personRepository.GetAll();

            Assert.AreEqual(numberOfPersons, result.Count, "Expected and actual count is not same");

            bool lessThanMinimum = result.Any(person => person.Id < minimumId);
            bool greaterThanMaximum = result.Any(person => person.Id > maximumId);

            Assert.IsFalse(lessThanMinimum);
            Assert.IsFalse(greaterThanMaximum);
        }


On this occasion I am creating the instance of RandomGenerator. Random generator has very good support for randomizing many of the primitive types. I have set the upper and lower bounds between 5 and 50. So the Ids will be assigned between these two bounds. I verify that the result does not contain any Id which is beyond these two bounds using the last two lines of the code.



Conclusion



My initial thoughts were that I wanted to cover another feature related to picking of random data from a pre defined list. I’ll leave it for another time. In the future post I also intend to demonstrate the Fluent Dates and the custom naming capabilities. I have been advocating the use of NBuilder in all our tests wherever we need to generate dummy data.



Hope this was helpful. I have uploaded the complete source code to http://dl.dropbox.com/u/1569964/SequenceAndPickUsingNBuilder.zip.



Until next time Happy Programming.

No comments:

Post a Comment

How Travis CI saved my time?

Background Some time back I created an Ansible playbook to install software and setup my Mac Book Pro . I put the code for this on GitHub . ...