Mock objects allow you to mimic/mock the behavior of real classes by guaranteeing determinate data output. This allows for easier testing since it isolates the code being tested and guards it against indeterminate data dependencies. A mocking framework is a library that easily creates and configures mock objects.

If mocking frameworks were not used, the process for creating mock objects would be more laborious. Mocking frameworks allow you to create these dependent classes without manually defining their implementation.

With mocks, you can set up an object’s method to return specific values based on specific inputs. You may also set various properties. You may even verify that the methods you set up are being called in the tested code. This ensures that the flow of the program happens as expected.

Mocking frameworks and preferred framework

Your unit test project may utilize numerous mocking frameworks. Some of these include the following::

  • Moq
  • NSubstitute
  • Rhino Mocks
  • FakeItEasy
  • NMock3

Due to its widespread use, we’ll use the Moq framework and demonstrate its operation below.

Using the Moq framework

Let’s have a look at the application code and test it using mocks.

Example application code

The application code below is an API. You can think of an API as a software that constantly runs and listens to outside requests. When it receives a request, it performs CRUD (create, read, update, and delete) operations on entries in a database. APIs therefore contain no front-end code. Each time you use an application like WhatsApp, send an instant message or check the weather on your phone, you’re using an API. When a client such as a web browser talks to an API, its request hits something called a controller, and in particular, the call is handled by an action method.

The API used in this example has only one controller. In the code below, the controller is found in Project/Controllers/OrderController.cs. The controller has one action method called CompleteOrder.

The API in this example handles orders in a web application order delivery system, for example, a web application that allows customers to place orders for flowers from a local florist. For the sake of simplicity, suppose this florist only has one item type that customers can order. In order to complete an order, the controller’s action method must receive recipient information (which including the recipients personal information, contained in a RecipientInfo object), delivery address details (which include details on where to deliver the package, contained in a DeliveryAddressInfo object) and notification details (which includes the contact details contained in a NotificationDetails object).

The call to this controller with the aforementioned arguments is shown in line 23 on the OrderController.cs file.

Once the controller receives this request with the required information, it calls a delivery service to deliver the package (the Deliver method of IDeliverService as invoked on line 25 in OrderController.cs). This service only needs the delivery address information. The delivery service returns true if it is able to deliver the package, and it returns false if it is unable to deliver the package. The reasons for being unable to deliver the package could be invalid delivery details, or a location that is not serviced by the courier company.

If the delivery service indicates that the delivery has been successfully initiated (line 26 of OrderController.cs), the notification service is utilized by invoking its Notify method (line 29 in OrderController.cs) with an appropriate message. This method will send the specified message to the recipient’s cellphone number as well as the recipient’s email address. Finally, a separate successful message is passed back to the frontend to indicate that the order is placed.

If the delivery service indicates that the delivery has not been successfully initiated (line 32 of OrderController.cs), the notification service is not utilized and only an unsuccessful message is passed to the frontend.

This behavior makes sense, because if we know the delivery service is happy to proceed with delivery, we only want to notify a customer (through cell phone and email) that a delivery has been initiated.

Our objective is to test the CompleteOrder action method in OrderController.

This code extract does not contain the implementation of the delivery or notification service, only its interface. You can think of the implementation of these services as possibly linking to another external API or conducting a database call.

The application is shown below. Make sure to go through the four .cs files contained in the Services and Controllers folders.

Get hands-on with 1200+ tech skills courses.