Category Archives: Unit testing

Unit Testing – Moq

Moq – it is library to mock your objects, return fake values. It is helpful when unit testing.
Imagine that you have Employee class and HrManager which performs any logic on Employees and you want to test this logic easily. Moq can be helpful in such situations.

See our code to be tested.

        public interface IEmployee
        {
            int SkillsLevel { get; }
            int ExperienceLevel { get; }
        }
        
        class Employee : IEmployee
        {
            public Employee(string lastName, int experience, int skills)
            {
                LastName = lastName;
                ExperienceLevel = experience;
                SkillsLevel = skills;
            }
            public string LastName { get; set; }

            public int ExperienceLevel { get; set; }
            public int SkillsLevel { get; set; }
        }

        class HrManager
        {
            public static IEmployee GetTheBestEmployee(IList<IEmployee> employees)
            {
                if (employees == null || employees.Count == 0)
                    throw new ArgumentNullException();

                return employees.ToList().OrderByDescending(e => e.SkillsLevel + e.ExperienceLevel).FirstOrDefault();
            }
        }

We would like to test HrManager.GetTheBestEmployee. We need a few instances of IEmployee to do this. Below you can see how mock can help in this situation. Notice that Employees are not instantiated in normal way. Mock allows you to setup only the required properties.

        [TestMethod]
        public void MoqUnitTest1()
        {
            var mockedEmployees = new List<IEmployee>();

            var e1 = new Moq.Mock<IEmployee>(); //create mocked IEmployee
            e1.Setup(x => x.SkillsLevel).Returns(5); //sets that SkillsLevel property will return value = 5, when called
            e1.Setup(x => x.ExperienceLevel).Returns(2); //sets that ExperienceLevel property will return value = 2, when called
            mockedEmployees.Add(e1.Object); //object here is IEmployee

            var e2 = new Moq.Mock<IEmployee>();
            e2.Setup(x => x.SkillsLevel).Returns(10);
            e2.Setup(x => x.ExperienceLevel).Returns(10);
            mockedEmployees.Add(e2.Object);

            var e3 = new Moq.Mock<IEmployee>();
            e3.Setup(x => x.SkillsLevel).Returns(2);
            e3.Setup(x => x.ExperienceLevel).Returns(1);
            mockedEmployees.Add(e3.Object);

            var theBestOne = HrManager.GetTheBestEmployee(mockedEmployees); //invoked method to be tested
            Assert.AreEqual<int>(10 * 10, theBestOne.SkillsLevel * theBestOne.ExperienceLevel); //assert
			
            e3.Verify(x => x.ExperienceLevel, Times.Once); //verifies whether property ExperienceLevel was called exactly once for this object
        }

More information: https://github.com/Moq/moq4/wiki/Quickstart

Unit Testing – Effort

Effort.EF – it is library to mock you EntityFramework database context and allow you test code without access to this ‘real’ database like MSSQL or Oracle.
Effort is installed together with EntityFramework and NMemory (in memory database).

Imagine you have a simple class with the only one method in it. This method counts people stored in database (Entity Framework is used).

    public class PeopleManager
    {
        public static int CountPeople(TSQL2012Entities entities)
        {
            return entities.ThePeople.Count();
        }
    }

You want to unit test this method, but without changing your real database. You can use Effort then.
Just create UnitTests project, install Effort.EF (using i.e. Nuget) add reference to your database project and project to be tested.
Now you can write like below.

        [TestMethod]
        public void PeopleManagerCountPeopleTransientTest()
        {
            //transient database context is created
            using (var context = new TSQL2012Entities(Effort.EntityConnectionFactory.CreateTransient("name=TSQL2012Entities")))
            {
                //entities are added
                context.ThePeople.Add(new ThePeople() { id = 0, firstname = "John", lastname = "Smith" });
                context.ThePeople.Add(new ThePeople() { id = 1, firstname = "Jane", lastname = "Brown" });
                
                //changes are stored into in memory database
                context.SaveChanges();

                //method is tested
                var peopleManagerCount = PeopleManager.CountPeople(context);
                Assert.AreEqual<int>(2, peopleManagerCount); //passed
            }
        }

That’s easy! There is only one thing to remember. When you create context using CreateTransient method, your in memory database is cleared always when you go outside the using clause. To avoid such behaviour you can use CreatePersisten method. See examples below.

        [TestMethod]
        public void PeopleManagerCountPeopleTransient2Test()
        {
            //transient database context is created, entites are added and stored
            using (var context = new TSQL2012Entities(Effort.EntityConnectionFactory.CreateTransient("name=TSQL2012Entities")))
            {
                context.ThePeople.Add(new ThePeople() { id = 0, firstname = "John", lastname = "Smith" });
                context.ThePeople.Add(new ThePeople() { id = 1, firstname = "Jane", lastname = "Brown" });
                context.SaveChanges();
            }

            //database context is cleared

            //method is tested, but database context is empty, so it fails
            using (var context = new TSQL2012Entities(Effort.EntityConnectionFactory.CreateTransient("name=TSQL2012Entities")))
            {
                var peopleManagerCount = PeopleManager.CountPeople(context);
                Assert.AreEqual<int>(2, peopleManagerCount);
            }
        }


        [TestMethod]
        public void PeopleManagerCountPeopleOnePersistentTest()
        {
            //persistent database context is created, entites are added and stored
            using (var context = new TSQL2012Entities(Effort.EntityConnectionFactory.CreatePersistent("connectionA", "name=TSQL2012Entities")))
            {
                context.ThePeople.Add(new ThePeople() { id = 0, firstname = "John", lastname = "Smith" });
                context.ThePeople.Add(new ThePeople() { id = 1, firstname = "Jane", lastname = "Brown" });
                context.SaveChanges();
            }

            //data is not cleared

            using (var context = new TSQL2012Entities(Effort.EntityConnectionFactory.CreatePersistent("connectionA", "name=TSQL2012Entities")))
            {
                //method is tested and test passes
                var peopleManagerCount = PeopleManager.CountPeople(context);
                Assert.AreEqual<int>(2, peopleManagerCount);
            }
        }

More information: https://effort.codeplex.com/

UnitTesting – not public methods

Sometime there is necessity to test internal or private methods. Normally it’s not possible as unit tests should generaly test public methods.
Still if you really need to test internal method see example below.
Imagine we have a class:

    public class Person
    {
        public Person(string firstName, string lastName, int age)
        {
            FirstName = firstName;
            LastName = lastName;
            Age = age;
        }


        public string FirstName { get; private set; }
        public string LastName { get; private set; }
        public int Age { get; private set; }


        internal int CalculateBirthYear() // the internal method to be tested
        {
            return DateTime.Now.Year - Age;
        }
    }

To test this internal method, you should add a line: “[assembly:InternalsVisibleTo(“Common.UnitTests”)]” to AssemblyInfo.cs file in your project.
Then internals are visible to your test project (project you put in AssemblyInfo).

Sometime there is necessity to test private methods. Imagine that method from the previous example is now private.
To access it you should use PrivateObject class in your test project. See example below:

        [TestMethod]
        public void CalculateBirthYearTest()
        {
            var person = new Person("John", "Smith", 20); // the object to test
            PrivateObject o = new PrivateObject(person);
            var year = (int)o.Invoke("CalculateBirthYear"); // the method name to test

            Assert.IsTrue(year == 1996);
        }

The other ways to access private methods is private accessor, but it is deprecated since VisualStudio 2012. One more way is reflection, but it is easier to use PrivateObject.

UnitTesting – Asserts, etc.

Unit testing is well known way to provide quality code. This article presents a few options how to return test result (success/ fail).
There are following classes we can make use of:
Assert – verifies specific conditions. It contains following methods (among others): IsTrue, AreEqual, Fail, IsNotNull.
CollectionAssert – verifies specific condition for collections, i.e.: AreEqual, AreEquivalent, DoesNotContain, IsSubsetOf.
StringAssert – verifies specific condition for string, i.e.: StartsWith, Contains, EndsWith, Matches.

What’s more there is ExpectedExceptionAttribute which marks a test method that it should throw an exception. When exception is not thrown, it means that test failed.

There is also special exception type AssertInconclusiveException. It means that test does not return any valid result (success or fail). It can be used i.e. when test method implementation is not finished yet.

See a few examples below. I implemented simple classes Person and SimpleMath and a few unit tests to test implemented functionalities.

        /// <summary>
        /// Assert.IsTrue checks whether given condition is satisfied
        /// </summary>
        [TestMethod]
        public void SimpleMathRandomDateTest()
        {
            var minDate = DateTime.Now.AddYears(-1);
            var maxDate = DateTime.Now;
            var randomDate = SimpleMath.GetRandomDate(minDate, maxDate);
            Assert.IsTrue(minDate <= randomDate && randomDate <= maxDate);
        }

        /// <summary>
        /// Assert.AreEqual checks whether two given objects are equal
        /// </summary>
        [TestMethod]
        public void SimpleMathMinOddTest()
        {
            var numbers = Enumerable.Range(10, 100);
            var result = SimpleMath.GetMinOddNumber(numbers);
            Assert.AreEqual(11, result);
        }

        /// <summary>
        /// CollectionAssert.AreEquivalent checks whether two collections have the same elements in the same quantity, but in any order
        /// </summary>
        [TestMethod]
        public void SimpleMathEvenNumbersEquivalentTest()
        {
            var min = 10;
            var max = 14;
            var expected = new List<int>() { 14, 10, 12 };
            var result = SimpleMath.GetEvenNumbers(min, max).ToList();
            CollectionAssert.AreEquivalent(expected, result); // returns success
        }

        /// <summary>
        /// CollectionAssert.AreEquivalent checks whether two collections have the same elements in the same quantity and order
        /// </summary>
        [TestMethod]
        public void SimpleMathEvenNumbersEqualTest()
        {
            var min = 10;
            var max = 14;
            var expected = new List<int>() { 14, 10, 12 };
            var result = SimpleMath.GetEvenNumbers(min, max).ToList();
            CollectionAssert.AreEqual(expected, result); //returns fail (as order of elements is different)
        }

        /// <summary>
        /// CollectionAssert.IsNotSubsetOf checks whether one collection is not a subset of the other
        /// </summary>
        [TestMethod]
        public void SimpleMathEvenAndOddNumbersNotSubset()
        {
            var min = 10;
            var max = 14;
            var resultEven = SimpleMath.GetEvenNumbers(min, max).ToList();
            var resultOdd = SimpleMath.GetOddNumbers(min, max).ToList();

            CollectionAssert.IsNotSubsetOf(resultEven, resultOdd);
        }
		
		/// <summary>
        /// StringAssert.Contains checks whether returned string contains specific substring
        /// </summary>
        [TestMethod]
        public void PeronGetFullNameTest()
        {
            var person = new Person("John", "Smith", 20);
            StringAssert.Contains(person.SayYourFullName(), person.LastName);
        }

        /// <summary>
        /// ExpectedException attribute marks that method should throw an exception
        /// </summary>
        [ExpectedException(typeof(ArgumentException))]
        [TestMethod]
        public void SimpleMathEvenNumbersInvalidInputTest()
        {
            var min = 16;
            var max = 14;
            var resultEven = SimpleMath.GetEvenNumbers(min, max).ToList();
        }

        /// <summary>
        /// AssertInconclusiveException is thrown and it means that test is skipped as it does not return any specific information yet
        /// </summary>
        [TestMethod]
        public void SimpleMathCalculateAreaTest()
        {
            throw new AssertInconclusiveException("Test not implemented yet.");
        }