C#-Fluent Interfaces for Unit Testing

Ghadeer Kenawi
6 min readJan 26, 2019

--

A fluent interface is one that communicates simply and clearly with users whether they are developers or software end users. Also, using a fluent Interface makes unit tests run faster than the regular unit tests, and makes writing unit tests easier with fewer code lines. This article will prove this with a simple understandable example.

One way to create a fluent interface is to use method chaining. The following example demonstrates how using fluent interfaces makes unit testing easier and shorter.

Let’s create a C# console application (solution) and add two projects; both have the same class; one will use a regular interface to consume and test the class and the other will use a fluent interface for the same job.

Create a C# console application, name it FluentInterfaces

Add a public class, name it MathMe.CS ;

MathMe class declares a global private integer, tMath , which is initialized to zero in the class constructor; this variable value will be changed by the methods; Add: which is void, adds an integer to tMath , and Multiply: which is void as well and multiply an integer by tMath .So the value of tMath will be changed after calling Add or/and Multiply, and we will use a getter only property, TMath to get the tMath’s final value.

Now to consume the MathMe class. In the Main method declare an instance of MathMe, m, and call the Add method two times passing the number 5, then call the Multiply method one time passing the number 10. Finally, get the value of tMath by calling the TMath getter property:

You can see in the code above we had to write about 6 lines to consume the MathMe class. Running the above code gives this result :

m.Add(5)=5+0 , m.Add(5)=5+5=10 , m.Multiply(10)=10*10=100

Now let’s create a unit test for the MathMe class:

Right click on the FluentInterfaces solution and choose AddNew Project

In the opened window choose Test → Unit Test Project

Call the unit test project FluentInterfaceUnitTest

Create a class, call it MathMeTests and decorate it with the [TestClass] annotation. In the class, create a test method, name it MathMe_Test_NoFluent(); this test method will create an instance of the MathMe class, calling the Add method, passing 5 as an argument, two times, then calling the Multiply method passing 10 as an argument, and finally calling the TMath getter and compare the result with 100.

Notice how it needed only 6 lines to conduct the unit test.

Running the unit test above gives this result:

The green check mark means the test ran successfully. Pay attention to the test running time, it is 8 ms.

Now let's create a fluent interface class for the MathMe class. The fluent interface class will have methods which wrap the MathMe class methods and return an object of same fluent interface class type. This way we can call these methods in a chain in one line of code when consuming the MathMe class.

Let's create a class, call it FluentMath. Because this class will be a wrapper to the MathMe class, it has a global variable of type MathMe , and a new instance of the MathMe is created in the FluentMath constructor.

Code explanation:

private MathMe m: Declaring a global variable type MathMe

public FluentMath(){ m = new MathMe()}: Creating a new instance of the MathMe class every time we create an instance of the FluentMath class (that is part of wrapping MathMe in FluentMath)

public FluentMath Add(int i){m.Add(i);return this;} :A public method that calls the Add(int i) method on the MathMe instance m and returns an instance of the FluentMath class.(wrapping the Add(int i) method from the MathMe into a FluentMath instance).

public FluentMath Multiply(int i){m.Multiply(i);return this;} :A public method that calls the Multiply(int i) method on the MathMe instance m and returns an instance of the FluentMath class.(wrapping the Multiply(int i) method from the MathMe into a FluentMath instance).

public int GetFinalNumber(){return m.TMath;} :A public method that calls the getter property TMath on the MathMe istance m which returns the final value of tMath.

Now we will use the FluentMath class to consume the MathMe class, as MathMe is now wrapped in FluentMath.We can do this by chaining the FluentMath methods passing arguments :

Notice it took only 2 lines of code to consume the FluentMath class, while with the regular interface it took 6 lines of code. Running the code above gives this result :

Add(5).Add(5).Multiply(10).GetFinalResult = 100

Now let's create a unit test for the FluentMath (testing the FluentMath class will also test the MathMe class as it is wrapped inside it):

Create a test method, call it MathMe_Test_Fluent() and decorate it with the [TestMethod] annotation; this test method will create an instance of the FluentMath class, and on that instance, it will call the Add , Multiply and GetFinalNumber methods in a chain and compare them with 100.

Notice how it needed only 2 lines to conduct the unit test. Running the unit test above gives this result:

The green check mark means the test run successfully. Pay attention to the test running time, it is 2 ms.

From the example above, we can see how using fluent interfaces makes it easier and faster to consume and unit test objects.

Other articles by Ghadeer Kenawi :

Threads in C# — Part1: Single-threaded vs Multi-threaded applications

Threads in C# -Part2- Behind the Scene — ParameterizedThreadStart

Threads in C# — Prevent Data Race using lock

Reflection in C# — How to load assembly and retrieve its metadata using Reflection

Solving Technical Mysteries: A Step-by-Step Guide to Being a Successful Software Support Engineer

Resources :

Fluent interface — Wikipedia

Fluent interfaces and Method Chaining in C# — Code Project

--

--

Ghadeer Kenawi

Professional Software Support Engineer at : IBMWatson ,UnitedHealthGroup ,Generac , IMC & more . LinkedIn : https://www.linkedin.com/in/ghadeer-kenawi-b480b311/