Software Testing!! BDD, AAA-Structure And Mocking For Unit Testing

Unit Tesing

Naming Convention of Test Method for Unit Testing Traditional Principle of Unit Test

One Test Method is written to test one and only one method and one assert method should test only one expectation at a time.

In short, the principle says – “one function/method and one assert per test method”.

Thus, let’s consider the example given below.

Comparing Traditional Principle to Real World Test Scenario

Verify the “GetSum” Method.

Test Cases

Positive Test Cases

TC1: The positive values are given, which should return the expected result.

Test Data-1: firstValue =5, secondValue =6

Negative Test Cases

TC2: Zero values are given should produce an invalid argument message.

Test Data-2: firstValue =0, secondValue =0.

TC3: The negative values are given and should produce an invalid argument message.

Test Data-3: firstValue =-5, secondValue =-6

Exceptional Test Cases

TC4: Threshold limit values are given should throw an exception message.

Test Data-4: firstValue =2147483647, secondValue =2147483647

Test Method Example

Now, according to Traditional principles, let’s write the test method for the “GetSum”.

Now, according to Traditional principle, we have covered the Positive Test Case with “Test Data-1” but what about negative and exceptional test cases?

How do we cover the negative and exceptional test cases with Traditional principle?

Behavior Driven Development (BDD) Why do we need BDD?

If we want to cover all of the behaviors of our test cases according to our previous example, then we need to follow some techniques, so that we can write down all of the behaviors of the method. Thus, BDD is the technique, which gives us the opportunity to fulfill all the test cases with standard and readable naming conventions. There are many techniques to write the naming convention of the test method but  it really depends on you and your preference. There is nothing right or wrong, if you follow some other technique. In short, we can say that in BDD, the components test their expected behavior.

Concept of BDD
1. Given- I am a beginner to BDD technique.I never used this technique before
2. When I read this tutorial for BDD
3. Then I have started linking to it and I have started using it. Finally, I learned it.

BDD Naming convention

Test Scenario

Verify GetSum Method

Test Cases

Positive Test Cases

TC1: The positive values given should return the expected result.

Test Data-1: firstValue =5, secondValue =6

Test Method - Naming Convection

• GivenPositiveVaidValuesAsParams_WhenGetSumIsCalled_ThenItShouldReturnSumValue

Given_Positive_Vaid_Values_As_Params_When_GetSum_Is_Called_Then_It_Should_Return_Sum_Value

Negative Test Cases

TC2: Zero values given should produce an invalid argument message.

Test Data-2: firstValue =0, secondValue =0

Test Method - Naming Convection:

GivenZeroValuesAsParams_WhenGetSumIsCalled_ThenItShouldThrowInvalidArgumentException

Given_Zero_Values_As_Params_When_GetSum_IsCalled_Then_It_Should_Throw_Invalid_Argument_Exception

TC3: The negative values given should produce an invalid argument message.

Test Data-3: firstValue =-5, secondValue =-6

Test Method - Naming Convection:

GivenNegativeValues_WhenGetSumIsCalled_ThenItShouldThrowInvalidArgumentException

Given_Negative_Values_When_GetSum_Is_Called_Then_It_Should_Throw_Invalid_Argument_Exception

Exceptional Test Cases

TC4: The threshold limit values given should throw an exception message.

Test Data-4: firstValue =2147483647, secondValue =2147483647

GivenMaxLimitValuesOfIntAsParams_WhenGetSumIsCalled_ThenItShouldThrowSumException

Given_Max_Limit_Values_Of_Int_As_Params_When_GetSum_IsCalled_Then_It_Should_Throw_Sum_Exception

Body Structure of the Test Method

There are no hard code rules for it. We generally follow the structure because it’s easy to read and understand. The general AAA structure is given below for Test Method.

AAA Structure
1. Arrange
2. Act
3. Assert
Arrange

In this arranged portion, we declare the variables and create the instance of the objects of the classes.

Act

The verified method is called in the portion. This is mainly used for passing the input parameters into the method and collecting the return result from the calling method.

Assert

In this portion, we compare the actual result of the calling method with the expected result. The test is passed or failed depending on this assert portion.

Object Mocking for Unit Testing Why Need Mock

Suppose you need to test the behavior of one method and it has an external Service or a method within it. During Unit testing, we avoid this kind of external dependencies and the mock technique gives us the facility to avoid the behavioral test of the external method or the Service. Let’s see the example.

This GetSum method has no external dependencies within it. So, it does not need object mocking.

Now, see the example given below of the class and this has two dependencies and those are CheckingAccount and SavingAccount.

Now, we want to verify the method “GetTotalMoneyByUserAccount” and it has two dependencies within it. To solve this kind of situation , we need mocking.

Mock Framework

There are many mock frameworks like Typemock Isolator, Rhino Mocks, Moq and NMock. You can use any one of them.

Requirement before making Mock
1. The class can’t be sealed.
2. The method can’t be static; but if you need, then use adaptor pattern.
3. You can mock if Interfaces, Abstract methods or properties or Virtual Methods or properties on concreate classes.

Select your Unit Testing Project. Go to Reference> Click right button of the mouse and select Manage NuGet Packages. Now, write down Moq into the search textbox and finally install it to your project.

Object Mocking, using Moq

In the code given above, line number 35 and 41, first we are creating instances of the object, using Mock.

1. Mock<IBankAccount> mockCheckingAccount = new Mock<IBankAccount>();
2. Mock<IBankAccount> mockSavingAccount = new Mock<IBankAccount>();

In the line numbers 38 and 44, we are implementing dummy implementation and if the GetMoneyByUserAccountNo method is called, then it will return 5 and 6. Thus, we don't need to know any internal logics of it.

1. mockCheckingAccount.Setup(a => a.GetMoneyByUserAccountNo(userAccountNumber)).Returns(5);
2. mockSavingAccount.Setup(a => a.GetMoneyByUserAccountNo(userAccountNumber)).Returns(6);

Now, the line number 48 shows that we are injecting the mock objects in to the class via constructor.

1. SimpleMath simpleMath = new SimpleMath(mockCheckingAccount.Object, mockSavingAccount.Object);

Secondly, in the line number 56 of the 'Act' portion; we call the verified method and it results into the actualResult variable. Finally, it returms an inline number 59. It gives us the actual result.

1. actualSumResult = simpleMath.GetTotalMoneyByUserAccount(userAccountNumber);

My main goal here is to introduce you with object mocking world. Thus, this is just an example. You can use any of the Mocking Frameworks.

How to test method call order with Moq

Download Moq.Sequences.dll from GitHub, followed by adding Moq.Sequences.dll as a reference in your .NET project and add a using Moq.Sequences; in your test class or simply use "Manage NuGet Packages” Manager, type "Moq.Sequences" and search for it. Finally, install it to your project and use it for your call as a reference.

Moq.Sequences support the following,

• Checks the order of the method calls, property gets and property sets.
• Allows you to specify the number of times; a call is made before the next one is expected.
• Allows inter-mixing of sequenced and non-sequenced expectations.