Click here to Skip to main content
14,244,068 members

Unit Testing - BDD, AAA Structure And Object Mocking

Rate this:
4.71 (12 votes)
Please Sign up or sign in to vote.
4.71 (12 votes)
8 May 2017CPOL
How to write the test method name, guideline for the naming convention, body structure inside the test method, and why need object mocking in the test method for unit testing.

Unit Testing

Naming Convention Of Test Method

Traditional Principle Of Unit Test

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

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

So, let’s consider the bellow example - 

Comparing Traditional Principle To Real World

Test Scenario

Verify the “GetSum” Method.

Test Cases

Positive Test Cases

TC1: Given positive values, should return expected result.

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

Negative Test Cases

TC2: Given zero values, should produce invalid argument message

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

TC3: Given negative values, should produce invalid argument message

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

Exceptional Test Cases

TC4: Given threshold limit values, should throw exception message

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

Test Method Example

Now according to the traditional principle, let’s write the test method for the “GetSum”

Now according to the 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 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 technique; so that, we can write down all of the behaviors of the method. So, the BDD which is the technique, gives us the opportunity to fulfill all of the test cases with standard and readable naming convention. Many peoples, many minds. There are many techniques to write the naming convention of the test method. But it really depends on only you and your preference. There is nothing right or wrong- if you follow some other different technique. Anyway, in a short, we can say that - in BDD, components test their expected behavior.

Concept Of BDD

  1. Given I am a beginner to the BDD technique, and I never use this technique before
  2. When I read this tutorial for BDD
  3. Then I have started to like it and finally I learn it.

BDD Naming Convention

Test Scenario - Verify the “GetSum” Method
 
Test Cases - Positive Test Cases

TC1: Given positive values, should return expected result

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

Test Method - Naming Convention:

  • GivenPositiveVaidValuesAsParams_WhenGetSumIsCalled_ThenItShouldReturnSumValue

More Readable -

  • Given_Positive_Vaid_Values_As_Params_When_GetSum_Is_Called_Then_It_Should_Return_Sum_Value

Negative Test Cases

TC2: Given zero values, should produce invalid argument message

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

Test Method - Naming Convention:

GivenZeroValuesAsParams_WhenGetSumIsCalled_ThenItShouldThrowInvalidArgumentException

More Readable -

Given_Zero_Values_As_Params_When_GetSum_IsCalled_Then_It_Should_Throw_Invalid_Argument_Exception

TC3: Given negative values, should produce invalid argument message

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

Test Method - Naming Convention:

GivenNegativeValues_WhenGetSumIsCalled_ThenItShouldThrowInvalidArgumentException

More Readable -

Given_Negative_Values_When_GetSum_Is_Called_Then_It_Should_Throw_Invalid_Argument_Exception

 

Exceptional Test Cases

TC4: Given threshold limit values, should throw exception message

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

GivenMaxLimitValuesOfIntAsParams_WhenGetSumIsCalled_ThenItShouldThrowSumException

More Readable -

Given_Max_Limit_Values_Of_Int_As_Params_When_GetSum_IsCalled_Then_It_Should_Throw_Sum_Exception

Body Structure Of Test Method

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

AAA - Structure

  1. Arrange
  2. Act
  3. Assert

Arrange

In this arrange portion, we declare 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 actual return result from the calling method.

Assert

In this portion, we compare the actual output result of the calling method with the expected output result. The test is passed or failed depends 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 method within it. During the unit testing, we have to avoid this kind of external dependencies and the mock technique gives us the facility to avoid the behavioral test of the external method or service.

Why?? because, according to the first principle,  we all know that - "Test the logic of the class only, nothing elseUnit test NEVER uses - configuration settings, a database, logging, another application/service/file/network I/O.
Anyway, let’s see the example -

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

Now, see the bellow example of the class and it has two dependencies and these are CheckingAccount and SavingAccount.

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

Mock Framework

There are many object mock framework 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 adapter pattern.
  3. You can mock if Interfaces, Abstract methods or properties or Virtual Methods or properties on concreate classes.

Adding MOQ  For Unit Testing Project

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 above example, look at the line number 35 and 41; here first, we are creating instances of the object using Moq.

Mock<IBankAccount> mockCheckingAccount = new Mock<IBankAccount>();

Mock<IBankAccount> mockSavingAccount = new Mock<IBankAccount>();

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

mockCheckingAccount.Setup(a => a.GetMoneyByUserAccountNo(userAccountNumber)).Returns(5);

mockSavingAccount.Setup(a => a.GetMoneyByUserAccountNo(userAccountNumber)).Returns(6);

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

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

Secondly, in the line number 56 of the 'Act' portion, we are calling the verified method and the output result goes into the actualSumResult variable and finally in line number 59, which is giving us the actual output result.

actualSumResult = simpleMath.GetTotalMoneyByUserAccount(userAccountNumber);

My main goal to introduce you with object mocking world. So, this is just an example. You can use any of the mocking framework.

How To Call Order Of Test Methods Using Moq Sequences

Download Moq.Sequences.dll from github then add 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 and type "Moq.Sequences" and serch it. Finally install it to your project and use it to your call as a reference.

Moq.Sequences supports the following:

  • Checks 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
  • Thread safe – each thread can have its own sequence

Example for calling methods sequentially

[TestMethod]
public void Given_Valid_Data_For_Object_Model_When_TestMethod_Is_Called_Then_It_Should_Be_Done_Successfully()
{
    ......
    ......

    //// Methods are called sequentially.
    using (Sequence.Create())
    {
        //// First, it is called
        Given_Valid_Template_Data_When_MethodSave_Is_Called_Then_It_Should_Be_Saved_Successfully();

         //// Second, it is called.
        Given_Valid_Template_Value_When_MethodUpdate_Is_Called_Then_It_Should_Update_Template();

        ///// Third, it is called.
        Given_Valid_Template_ID_When_DeleteTemplate_Is_Called_Then_It_Should_Delete_Template();
    }

    ......
    ......
}
[TestMethod]
public void Given_Valid_Data_For_Model_When_TestMethod_Is_Called_Then_It_Should_Be_Done_Successfully()
{
    ......
    ......
    ///
    using (Sequence.Create())
    {
        //// Methods are called sequentially.
        mockObject.Setup(x => x.MethodA()).InSequence();
        mockObject.Setup(x=>x.MethodB()).InSequence(Times.AtMostOnce());
        mockObject.Setup(x=> x.MethodC()).InSequence(Times.Once());
    }
    ......
    ......
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

HR Rony
Engineer
United States United States
Motivated software developer in web/mobile application development, architecture design, and multi-layer implementation. Well-versed in multiple programming languages and platforms. Demonstrated success in UI, integration, and automated unit testing.

Comments and Discussions

 
QuestionGreat article! Also read my article on the same topic. Pin
Sudipta Chaudhari14-Jun-18 6:57
memberSudipta Chaudhari14-Jun-18 6:57 
PraiseGreat Summary Pin
fly19876-May-17 22:59
memberfly19876-May-17 22:59 
GeneralRe: Great Summary Pin
HR Rony8-May-17 5:23
memberHR Rony8-May-17 5:23 
GeneralRe: Great Summary Pin
fly19878-May-17 16:36
memberfly19878-May-17 16:36 
QuestionGreat article Pin
Robert_Dyball3-May-17 12:58
professionalRobert_Dyball3-May-17 12:58 
AnswerRe: Great article Pin
HR Rony4-May-17 5:33
memberHR Rony4-May-17 5:33 
PraiseGood points! Pin
quicoli17-Apr-17 2:53
memberquicoli17-Apr-17 2:53 
GeneralRe: Good points! Pin
HR Rony17-Apr-17 5:02
memberHR Rony17-Apr-17 5:02 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Article
Posted 16 Apr 2017

Stats

17.9K views
114 downloads
13 bookmarked