Wednesday, August 14, 2019

C# Unit Testing – How Do Verify Exception has been thrown in unit test

In this blog, we will learn how to write the unit test that verify, the exception has been thrown in case of invalid input or validation rules violation.
There are two way, we can verify that calling method has been throw specified type exception:

·         Assert.ThrowException method
·         ExpectedException attribute 

Here is a business class, which perform the validation rule and create or update person record and if validation rule is dishonored, it throw validation exception

What are the benefits of unit testing?

public class PersonEngine
    {
        IPersonReposirty _personReposirty;

        public PersonEngine(IPersonReposirty personReposirty)
        {
            _personReposirty = personReposirty;
        }

        public Person CreatePerson(Person person)
        {
            if(person.PersonName == null)
            {
                throw new ValidationException("Person Name Cannot be blank");
            }

            if (!validSSN(person.SSN))
            {
                throw new ValidationException("SSN is not valid");
            }

           return _personReposirty.CreatePerson(person);

        }      

        private bool validSSN(string ssn)
        {
            return Regex.IsMatch(ssn, @"^(?:\d{9}|\d{3}-\d{2}-\d{4})$");        
        }
    }


The PersonEngine Class performs the below validations before call to repository object to create a new person record.

·         Person Name should not be blank.
·         SSN should be invalid format.

By Using Assert.ThrowsException method:

Here are unit tests which use Assert.ThrowsException method to verify that if the business or validation are failed, it throw Validation Exception

1.   Verify Person Name, Person Name is required

        [TestMethod]
        public void Verify_Person_Name_Blank()
        {
            PersonEngine personEngine;

            Mock<IPersonReposirty> _mockRepository = new Mock<IPersonReposirty>();
            Person person = new Person
            {
                PersonName = null,
                SSN = "123456789"
            };

            _mockRepository.Setup(x => x.CreatePerson(person)).Returns(person);

            personEngine = new PersonEngine(_mockRepository.Object);

            Assert.ThrowsException<ValidationException>(() =>                          personEngine.CreatePerson(person));
        }

2.   Verify SSN Length, It should be 9 digit

            [TestMethod]
        public void Verify_SSN_InValid_Length()
        {
            PersonEngine personEngine;

            Mock<IPersonReposirty> _mockRepository = new Mock<IPersonReposirty>();
            Person person = new Person
            {
                PersonName = new PersonName { FirstName = "Tom", LastName = "Dick" },
                SSN = "12345678"
            };

            _mockRepository.Setup(x => x.CreatePerson(person)).Returns(person);

            personEngine = new PersonEngine(_mockRepository.Object);

            Assert.ThrowsException<ValidationException>(() =>                          personEngine.CreatePerson(person));
        }

3.   Verify SSN Format , It should be {3}-{2}-{4}

        [TestMethod]
        public void Verify_SSN_InValid_Format()
        {
            PersonEngine personEngine;

            Mock<IPersonReposirty> _mockRepository = new Mock<IPersonReposirty>();
            Person person = new Person
            {
                PersonName = new PersonName { FirstName = "Tom", LastName = "Dick" },
                SSN = "1234-567-89"
            };

            _mockRepository.Setup(x => x.CreatePerson(person)).Returns(person);

            personEngine = new PersonEngine(_mockRepository.Object);

            Assert.ThrowsException<ValidationException>(() =>                          personEngine.CreatePerson(person));
        }


Here is unit test result:




By Using ExpectedException Attribute:

Here are unit tests which use  ExpectedException Attribute to verify that if the business or validation are failed, it throw Validation Exception

1.   Verify Person Name, Person Name is required

         [TestMethod]
        [ExpectedException(typeof(ValidationException))]
        public void Verify_Person_Name_Blank()
        {
            PersonEngine personEngine;

            Mock<IPersonReposirty> _mockRepository = new Mock<IPersonReposirty>();
            Person person = new Person
            {
                PersonName = null,
                SSN = "123456789"
            };

            _mockRepository.Setup(x => x.CreatePerson(person)).Returns(person);

            personEngine = new PersonEngine(_mockRepository.Object);

            personEngine.CreatePerson(person);          
        }

2.   Verify SSN Length, It should be 9 digit

          [TestMethod]
        [ExpectedException(typeof(ValidationException))]
        public void Verify_SSN_InValid_Length()
        {
            PersonEngine personEngine;

            Mock<IPersonReposirty> _mockRepository = new Mock<IPersonReposirty>();
            Person person = new Person
            {
                PersonName = new PersonName { FirstName = "Tom", LastName = "Dick" },
                SSN = "12345678"
            };

            _mockRepository.Setup(x => x.CreatePerson(person)).Returns(person);

            personEngine = new PersonEngine(_mockRepository.Object);

            personEngine.CreatePerson(person);
        }

3.   Verify SSN Format , It should be {3}-{2}-{4}

        [TestMethod]
        [ExpectedException(typeof(ValidationException))]
        public void Verify_SSN_InValid_Format()
        {
            PersonEngine personEngine;

            Mock<IPersonReposirty> _mockRepository = new Mock<IPersonReposirty>();
            Person person = new Person
            {
                PersonName = new PersonName { FirstName = "Tom", LastName = "Dick" },
                SSN = "1234-567-89"
            };

            _mockRepository.Setup(x => x.CreatePerson(person)).Returns(person);

            personEngine = new PersonEngine(_mockRepository.Object);

            personEngine.CreatePerson(person);
        }

No comments:

SQL Server - Identify unused indexes

 In this blog, we learn about the index usage information (SYS.DM_DB_INDEX_USAGE_STATS) and analyze the index usage data (USER_SEEKS, USER_S...