Getting started with xUnit
Tags: dotnetcore, unittesting, csharp, xunit
Published: 2018-12-06 22:14:33

---
title: Getting started with xUnit
published: true
tags: dotnet-core,unit-testing,c-sharp,xUnit
canonical_url: https://medium.com/@kritner/getting-started-with-xunit-ecc09843d086
cover_image: https://cdn-images-1.medium.com/max/1024/0*McmE7cnYoCCtsXjC
---

Cover Photo by <a href="https://unsplash.com/@maxcodes?utm_source=medium&amp;utm_medium=referral">Max Nelson</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption>

I’ve worked with MSTest and NUnit previously, but for whatever reason not with xUnit. Thankfully, coming from either framework seemed to translate pretty easily into xUnit.

In the recent post I did:

[Your favorite/most useful extension methods?](https://dev.to/kritner/your-favoritemost-useful-extension-methods-51il)

I explored working with xUnit for the first time, to help to ensure the extension methods I was implementing were working as I intended. Though I had written previously about the extension methods, I hadn’t covered the testing of them; I thought that deserved its own post.

### What is unit testing?

If you’ve never worked with unit testing before, [wikipedia](https://en.wikipedia.org/wiki/Unit_testing) describes them as:

> In [computer programming](https://en.wikipedia.org/wiki/Computer_programming), **unit testing** is a [software testing](https://en.wikipedia.org/wiki/Software_testing) method by which individual units of [source code](https://en.wikipedia.org/wiki/Source_code), sets of one or more computer program modules together with associated control data, usage procedures, and operating procedures, are tested to determine whether they are fit for use.[[1]](https://en.wikipedia.org/wiki/Unit_testing#cite_note-kolawa-1)

The way I usually describe it is: unit testing is the process of ensuring expected outcomes from a piece of code — ideally a single function — without relying on external resources. When unit testing, anything that’s needed outside of the method under test should be provided via an abstraction, rather than concretion — to ensure that you are testing *only* the method under test. The dependencies needed by the method can be provided by making use of [mocks, fakes, and/or stubs](https://en.wikipedia.org/wiki/Mock_object) — pieces of code programmed to exhibit specific behavior to help cover all potential “branches” within your code.

### MSTest, nUnit, and xUnit differences

Not having worked with MSTest since prior to it allowing multiple testing scenarios to a single test, I wasn’t sure how to describe the differences. Luckily, a quick google search pointed me to a “differences” page written up on the xUnit site:

[Comparing xUnit.net to other frameworks > xUnit.net](https://xunit.github.io/docs/comparisons)

It appears that all the frameworks do the same thing more or less; though I find it interesting that .net core seems to pretty extensively use xUnit over their own testing framework of MSTest.

### Project Setup

Thankfully, there is a project template (at least with whatever VS install options I used) to create an xUnit test project. If you do not have this, you just need to add the following NuGet packages to a project:

- Microsoft.NET.Test.Sdk
- xunit
- xunit.runner.visualstudio

Your csproj file should look like this(ish):

{% gist https://gist.github.com/Kritner/09ba85620b35ce0e964f620596674e20 %}

### Testing a method

I picked a method from my extension methods post, that would allow me to make use of various types of using xUnit:

- Fact — this piece of code does [this] thing
- Theory — this piece of code does [this] thing, and here are multiple examples of that occurring with separate data driven tests.
- Expected Exception — this type of test is checking the code throws an exception of an expected type.

The method we’ll be testing with is:

```cs
/// <summary>
/// Attempts to find the first item in <see cref="items"/> 
/// meeting <see cref="Predicate{T}"/>. 
/// 
/// Returns the <see cref="true"/> when item found, 
/// <see cref="false"/> when not.
/// 
/// Found result is contained within out parameter <see cref="result"/>.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="items"></param>
/// <param name="predicate"></param>
/// <param name="result"></param>
/// <returns><see cref="true"/> when item found. <see cref="false"/> otherwise.</returns>
/// <exception cref="ArgumentNullException">
/// Thrown when <see cref="items"/> or <see cref="Predicate{T}"/> is null.
/// </exception>
public static bool TryFirst<T>(
 this IEnumerable<T> items, 
 Func<T, bool> predicate, 
 out T result
)
{
 if (items == null)
  throw new ArgumentNullException(nameof(items));
 if (predicate == null)
  throw new ArgumentNullException(nameof(predicate));

 result = default(T);
 foreach (var item in items)
 {
  if (predicate(item))
  {
   result = item;
   return true;
  }
 }
 return false;
}
```

The above extension method exists on `IEnumerable<T>` and works very similar to built in methods like `int.TryParse(...)`. This method returns true/false depending on whether or not an item is found based on the predicate, and that item is then contained within the out parameter of result.

How can we test this? _What_ in this method _can_ be tested? Here are some of the things that can be tested:

- `ArgumentNullException` if `items` is `null`.
- `ArgumentNullException` if `predicate` is `null`
- `false` when no item is found matching the `predicate`
- `true` when an `item` is found matching the `predicate`
- `result` contains the found `item` that met the `predicate`

#### Test class setup

Let’s start with our test class:

```cs
public class EnumerableExtensionTests
{
 
}
```

One thing I like about xUnit over nUnit, is that I don’t need to decorate the class in any way to indicate it is a class with unit tests. We’ll need (or rather, I’d like) a class to play around with, since our extension method works on a generic `IEnumerable<T>`. We can introduce a little fake class for testing purposes by updating our test class to:

```cs
public class EnumerableExtensionTests
{
 public class EnumerableTest
 {
  public int SomeInt { get; set; }
 }

  public static List<object[]> EnumerableTestData =>
  new List<object[]>()
  {
   new object[]
   {
    new List<EnumerableTest>()
    {
     new EnumerableTest() { SomeInt = 1 },
     new EnumerableTest() { SomeInt = 42 },
    }
   }
  };
}
```

In the above, I’m defining a new type, to be used only by this test class, that has a property of `SomeInt`. Additionally, I set up some static data we will be using shortly to help ensure our method is working properly.

#### Let’s get into the tests

We have two ways our extension method can throw an `ArgumentNullException `— when either items or `predicate` is `null`. Let’s see what tests for those conditions can look like.

- `ArgumentNullException` if `items` is null.

```cs
[Fact]
public void ShouldThrowWhenItemsNull()
{
 List<EnumerableTest> items = null;

 Assert.Throws<ArgumentNullException>(() => 
  items.TryFirst(t => t.SomeInt == 42, out var result)
 );
}
```

In the above, we’re setting up our `IEnumerable<T>` to be `null`, covering one of our branches in our method — this tests that when the items are `null`, an `ArgumentNullException` is thrown. NUnit decorated tests as `[Test]`, here the test (in xUnit) is decorated as `[Fact]`.

- `ArgumentNullException` if `predicate` is `null`

```cs
[Theory]
[MemberData(nameof(EnumerableTestData))]
public void ShouldThrowWhenPredicateNull(List<EnumerableTest> items)
{
  Assert.Throws<ArgumentNullException>(() =>
  items.TryFirst(null, out var result)
 );
}
```

In the above, I’m using a `[Theory]` rather than `[Fact] `— I’m not sure that I *have* to in this case, but from my NUnit days, I couldn’t instantiate instances of non primitives within an attribute, though I’m not sure if that’s a limitation of NUnit, or c#. Anyway, in this test I’m providing the sample data to the method that was defined in the test class definition, and then providing a `null` `predicate`; the second condition for throwing a `ArgumentNullException`.

- `false` when an no `item` is found meeting the `predicate`

In this test, we want to provide a valid `IEnumerable<T>` to the extension method, with a valid `predicate`; though in this case our `predicate` is not a match on any `item` within `items`.

```cs
[Theory]
[MemberData(nameof(EnumerableTestData))]
public void ShouldReturnFalseWhenDataNotFound(List<EnumerableTest> items)
{
 var found = items.TryFirst(
  t => t.SomeInt == 100, out var result
 );

 Assert.False(found);
}
```

In the above, we’re making sure that the `boolean` returned from our function is `false`, since 100 does not exist within our sample data.

- `true` when an `item` is found meeting the `predicate`

Next, we’ll make sure that the result of the extension method is `true` when the `predicate` matches an `item` within the `items`.

```cs
[Theory]
[MemberData(nameof(EnumerableTestData))]
public void ShouldReturnTrueWhenDataFound(List<EnumerableTest> items)
{
 var found = items.TryFirst(
  t => t.SomeInt == 42, out var result
 );

 Assert.True(found);
}
```

The above is really similar to the `false` test, except we’re providing a valid `predicate` that does match an `item` within `items`.

- `result` contains the found `item` that met the `predicate`

Our final test, ensures that we retrieve the `item` in the out results parameter from the function:

```cs
[Theory]
[MemberData(nameof(EnumerableTestData))]
public void ShouldReturnDataWhenDataFound(List<EnumerableTest> items)
{
 var dataToSearch = 42;

 var found = items.TryFirst(
  t => t.SomeInt == dataToSearch, out var result
 );

 Assert.Equal(dataToSearch, result.SomeInt);
}
```

It looks like this when running our tests:

![](https://cdn-images-1.medium.com/max/746/1*YE92aU9VR_FTVBvQf2JUrQ.png)

xUnit and nUnit seem to be pretty similar in syntax and structure, though I do enjoy the notion of using constructors for test class setup, rather than `SetUp` as with nUnit.

The code from this post can be found:

[Kritner-Blogs/ExtensionMethods](https://github.com/Kritner-Blogs/ExtensionMethods/releases/tag/v1.0.1)

Related:

- [Your Favorite/Most Useful Extension Methods](https://medium.com/@kritner/your-favorite-most-useful-extension-methods-a63f4dc1cff2?source=friends_link&sk=fb8f681f2a963ac437a3fcad0eb13da4)