Kentico 12: Design Patterns Part 2 - Writing Unit Tests
Tags: kentico, unittesting, dotnet, aspnet
Published: 2019-06-01 01:11:14

---
title: Kentico 12: Design Patterns Part 2 - Writing Unit Tests
published: true
tags: kentico,unit-testing,dotnet,aspnet
canonical_url: https://medium.com/@seangwright/kentico-12-design-patterns-part-2-272839f7a70d
series: Kentico 12 - Design Patterns
description: Learn some helpful design patterns for writing effective unit tests for Kentico 12 MVC libraries
---
![](https://cdn-images-1.medium.com/max/1024/0*aM7L3FM1cq4rPzuO)<figcaption>Photo by <a href="https://unsplash.com/@alecuffia?utm_source=medium&amp;utm_medium=referral">José Alejandro Cuffia</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption>

## A Quick Review

In [Part 1](https://dev.to/wiredviews/kentico-12-design-patterns-part-1-3ga8-temp-slug-8278822) of this series, I detailed why we should be careful taking dependencies on static globals, like `SiteContext` in our Kentico code.

To summarize, these static globals provide us access to the state of our application, but they make assumptions about how and where our application is running.

A live ASP.NET Kentico 12 MVC application is a very different thing from a running unit test project, and `SiteContext` will provide values that you as the developer have no control over when it is being accessed within a unit test.

The goal of a unit test is to arrange a scenario by simulating an application state, act on that scenario, and then assert on the results of that action. If we do not have the ability to arrange that initial state, as is the case with `SiteContext`, we cannot effectively test the units of code that depend on it.

By taking a dependency on an interface instead of the static global, like `ISiteContext`, we can use the real `SiteContext` as the implementation of that interface at runtime in our application but use a stub at test time.

If we look at the `KenticoSettingConfigProvider` we created in Part 1, we can see we have all the pieces in place to write our tests.

{% gist https://gist.github.com/seangwright/be623bae6070ac64d99a91f3f06ab934 %}

Now that we’ve quickly reviewed our previous work, let’s write some tests! 🤓

## Writing Our First Test

We create our test class using Kentico’s `UnitTests` base class, which is required to be able to interact with `*Info` and `*InfoProvider` classes without needing to have access to a real database.

{% gist https://gist.github.com/seangwright/84a91a80c3e137f09b08aa6d4ef07801 %}

We can see here that I’ve created a new test class `KenticoSettingConfigProviderTests`.

I’ve told `NUnit` that it should discover and run the tests in this class by adding the `[TestFixture]` attribute to my class and the `[Test]` attribute to my test method.

In this first test I am asserting that if I do not provide a valid parameter to my constructor, then it will throw an exception.

> The `.Should()` assertion syntax comes from the [FluentAssertions](https://fluentassertions.com/) library, which is my preferred tool for writing readable assertions.

So far this is pretty standard unit testing. Let’s move on to testing our Kentico specific code.

## Unit Testing Patterns and Conventions

We want to test the various methods of our `KenticoSettingConfigProvider`.

It uses Kentico’s `SettingKeyInfoProvider` to access settings from the database and our interface `ISiteContext`, which is an abstraction over `SiteContext`, when we want a site specific setting instead of a global one.

Here is an example of testing the `GetString` method to get a site-specific setting value:

{% gist https://gist.github.com/seangwright/b9e3d3bf1ef601931aeb4a9f59007d32 %}

There’s a lot going on here that we haven’t discussed yet 🤯, so let’s unpack it.

First, I’ve added a new attribute, `[AutoDomainData]`, to the test method. `[AutoDomainData]` uses the [AutoFixture](https://github.com/AutoFixture/AutoFixture) library to create randomly generated values, for all primitive types, that I can use to set up the state of my test. Any parameter I specify in my test method signature will be populated with a non-null, generated value.

The implementation of this attribute is pretty simple:

{% gist https://gist.github.com/seangwright/beadf91dd034841451d4e50632b622ab %}

🙋You might be wondering, “If it’s so important to control the state of our test, why do we use a library to generate random values to test against?”

That’s a great question!⚡

Some state in a unit test is very specific and needs to have explicitly defined values to ensure the test operates how we want. But other state in our test flows through the entire test without being modified, or if it is modified it is changed in a predictable way, independent of the exact value.

> #### _It’s more important that the state is consistent than having a specific set of values._

In the test case above, I’m not actually concerned with the value of the setting I’m trying to retrieve. I’m only attempting to verify it’s the value that `SettingKeyInfoProvider` will return for the given setting key.

I’m also not concerned with the exact value of the setting key — the only requirement is that it is directly associated with the value I’m expecting to be returned!😮

I could change this test so that each part of the test state has an explicit value as seen below:

{% gist https://gist.github.com/seangwright/398f867459a1690cc2f12c52eabe6469 %}

The issue I have with this approach is that now another developer reading the test might wonder why I picked those specific values. Are they important? Do all setting keys need to be suffixed with a numeral? If I use a `siteId` other than 3 in a later test, is that significant? 🤔

In order to keep the focus of the test on the “Subject Under Test” (`sut` in the examples above), I want to remove any distractions. I consider the values of the state I’m setting up to be distractions in this case. 🧐

> While the values of the state might not matter, the state itself has to be internally consistent. If I pass `keyName` to my `.GetString()` method but I use a different value when mocking my `SettingKeyInfoProvider` data, my test will fail.

> This is an example of how the state I’m simulating flows through the test, and while the exact state values might not matter, all pieces of my test must use the provided state in the correct way. **The state must be consistent**.

## Faking Data When Testing with Kentico

Let’s now take a look at some of the utilities I’m using to ensure my test state is correctly initialized.

The `SettingInfoProviderFixture` is a reusable helper class that can ensure the fake data that `SettingInfoProvider` and `SiteInfoProvider` access is initialized.

{% gist https://gist.github.com/seangwright/1c523e21e6fe1c1d08dc97dbb60074c1 %}

I’m using the Kentico `AutomatedTestsWithData` abstract class as a base class for my fixture. This gives me access to the `Fake<,>()`, method which is used to initialize the state of data the `*InfoProvider` classes will access. 👩‍💻

> Normally you would have these calls to `Fake<,>()` in your test methods, but this setup code is pretty noisy and distracts from the “Subject Under Test”.

> The `UnitTests` class, from which all Kentico unit test classes must inherit, itself inherits from `AutomatedTestsWithData` so this is a convenient way to move some of that arranging of state out of the test method.

## Stubbing Our Context

If we look back at the way we previously defined `ISiteContext`, we can see it provides read-only access to a couple of values — `Site`, `SiteId`, and `SiteName`.

{% gist https://gist.github.com/seangwright/43fff4642e30658b8895a7baf279573b %}

The `ISiteContext` that is defined as a method parameter in the unit test method is created by AutoFixture with the help of a mocking library [NSubstitute](https://nsubstitute.github.io/).

{% gist https://gist.github.com/seangwright/b9e3d3bf1ef601931aeb4a9f59007d32 %}

This `ISiteContext` is not null but it also doesn’t have any actual behavior — that is up to us to define.

Above, we can see the call `siteContext.SiteName.Returns()`, which is using the NSubstitute `.Returns()` extension method. It allows us to explicitly define what value will be returned by this stub during the execution of our test.

We know that `KenticoSettingConfigProvider`, internally, uses `siteContext.SiteName` to query the `SettingInfoProvider` data for a setting value that matches the given setting key and site:

![](https://cdn-images-1.medium.com/max/887/1*FcCEAkNOexHDpPOj9YdEvQ.jpeg)

Here again you can see how the randomly generated state flows through our test in a consistent way to ensure that the state we act against is arranged in the same was as a real Kentico site. 👍🏽

Once we have all of our state arranged for our test, we can act on that state by calling `.GetString()` on our `KenticoSettingConfigProvider`.

Finally, we get a response from the method call, and we can assert that the value returned should match the value we arranged in our initial state configuration.

Executing our unit test shows that the test passes!🌟💥🤸🏾‍♀️

## What We Accomplished

Looking back we can see how several decisions we made in designing our test came together to help us ensure our test would clearly show what was being tested, arrange our state consistently, and also pass despite not running in a live environment.

- Integrating AutoFixture with NUnit allowed us to push the focus of our test away from the exact state we were simulating and onto the behavior of the “Subject Under Test”.✔️
- Moving the setup of Kentico `*InfoProvider` data into a separate fixture class gave us a reusable tool for writing tests and also reduced the state arrangement distractions in our test method.✔️
- Since we relied on `ISiteContext` instead of the static global `SiteContext` we were able to ensure that our arranged state was not only flowed through our method call and `*InfoProvider` data stores, but also into the simulated request context that would, in a real running application, reflect the correct Kentico site the current request was associated with.✔️

I hope you found this review, of what I believe to be effective unit testing patterns when working with Kentico, helpful. 👍

Next in this blog series, I’m going to cover some organizational patterns in Kentico 12 MVC projects that can help you scale your applications and manage complexity using thoughtful conventions. 👨‍🏫

> Have you read my previous post in this series “Kentico 12: Design patterns Part 1 — Writing Testable Code”?

[Kentico 12: Design Patterns Part 1](https://dev.to/seangwright/kentico-12-design-patterns-part-1-writing-testable-code-258a)