---
title: "Unit Testing dotnet new Templates - Muhammad Rehan Saeed"
description: "It's difficult to know if your 'dotnet new' based project will work if they have lots of options, in this post I show how to unit test them."
canonical_url: "https://rehansaeed.com/unit-testing-dotnet-new-templates/"
last_updated: "2019-08-21T00:00:00+00:00"
meta:
  author: "Muhammad Rehan Saeed"
  keywords: ".NET,dotnet,dotnet new,NuGet,Project Template"
  "og:description": "It's difficult to know if your 'dotnet new' based project will work if they have lots of options, in this post I show how to unit test them."
  "og:image": "https://rehansaeed.com/_og/s/o_967078d8ae7b4a05.png"
  "og:image:alt": "Unit Testing dotnet new Templates - Muhammad Rehan Saeed"
  "og:image:height": "630"
  "og:image:type": image/png
  "og:image:width": "1200"
  "og:title": "Unit Testing dotnet new Templates"
  "twitter:image": "https://rehansaeed.com/_og/s/o_967078d8ae7b4a05.png"
  "twitter:image:alt": "Unit Testing dotnet new Templates - Muhammad Rehan Saeed"
---

> Index of every page on this site: [llms.txt](https://rehansaeed.com/llms.txt)

# [Unit Testing dotnet new Templates](https://rehansaeed.com/unit-testing-dotnet-new-templates/)

Posted 21 August 2019 - **3 min read**

![Microsoft .NET](https://rehansaeed.com/_ipx/f_png&s_2560x1440/images/hero/Microsoft-.NET-1366x768.png)

1. [dotnet new - Custom Project Templates Using dotnet new](https://rehansaeed.com/custom-project-templates-using-dotnet-new/)
2. [dotnet new - dotnet new Feature Selection](https://rehansaeed.com/dotnet-new-feature-selection/)
3. [dotnet new - Unit Testing dotnet new Templates](https://rehansaeed.com/unit-testing-dotnet-new-templates/)

As I talked about in my previous post some time ago about `dotnet new` project templates, it's possible to enable feature selection, so that developers can toggle certain features of a project template on or off. This is not a feature that many templates in the wild use a lot. Quite often I've seen templates have no optional features or only a few. One reason is that it gets very complicated to test that toggling your optional features doesn't break the generated project in some way by stopping it from building for example. This is why I decided to write a small unit test helper library for `dotnet new` project templates. It is unit test framework agnostic and can work with xUnit, NUnit, MSTest or any other unit test framework.

## Link to this sectionExample Usage

Below is an example showing how you can use it inside an xUnit test project.

```cs
public class ApiTemplateTest
{
    public ApiTemplateTest() => DotnetNew.Install<ApiTemplateTest>("ApiTemplate.sln").Wait();

    [Theory]
    [InlineData("StatusEndpointOn", "status-endpoint=true")]
    [InlineData("StatusEndpointOff", "status-endpoint=false")]
    public async Task RestoreAndBuild_CustomArguments_IsSuccessful(string name, params string[] arguments)
    {
        using (var tempDirectory = TempDirectory.NewTempDirectory())
        {
            var dictionary = arguments
                .Select(x => x.Split('=', StringSplitOptions.RemoveEmptyEntries))
                .ToDictionary(x => x.First(), x => x.Last());
            var project = await tempDirectory.DotnetNew("api", name, dictionary);
            await project.DotnetRestore();
            await project.DotnetBuild();
        }
    }

    [Fact]
    public async Task Run_DefaultArguments_IsSuccessful()
    {
        using (var tempDirectory = TempDirectory.NewTempDirectory())
        {
            var project = await tempDirectory.DotnetNew("api", "DefaultArguments");
            await project.DotnetRestore();
            await project.DotnetBuild();
            await project.DotnetRun(
                @"Source\DefaultArguments",
                async (httpClient, httpsClient) =>
                {
                    var httpResponse = await httpsClient.GetAsync("status");
                    Assert.Equal(HttpStatusCode.OK, httpResponse.StatusCode);
                });
        }
    }
}
```

The first thing it does in the constructor is install the `dotnet new` project templates in your solution. It needs to know the name of the solution file. It then walks the sub-directory tree below your solution file and installs all project templates for you.

If we then look at the first unit test, we first need a temporary directory, where we can create a project from our `dotnet new` project template. We will generate a project from the template in this directory and then delete the directory at the end of the test. We then run `dotnet new` with the name of a project template, the name we want to give to the generated project and any custom arguments that particular project template supports. Using xUnit, I've parametrised the arguments, so we can run multiple tests while tweaking the arguments for each test. Running `dotnet new` returns a project which contains some metadata about the project that we've just created and we can also use it to further `dotnet` commands against.

Finally, we run `dotnet restore` and `dotnet build` against the project. So this test ensures that toggling the `StatusEndpointOn` option on our project template doesn't stop the generated project from restoring NuGet packages or building successfully.

The second unit test method is where it gets really cool. If the project template is an ASP.NET Core project, we can use `dotnet run` to start the project listening on some random free ports on the machine. The unit test framework then gives you two `HttpClient`'s (One for HTTP and one for HTTPS) with which to call your newly generated project. In summary, not only can you test that the generated projects build, you can test that the features in your generated project work as they should.

This API is pretty similar to the ASP.NET Core `TestHost` API that also gives you a `HttpClient` to test the API with. The difference is that this framework is actually running the app using the `dotnet run` command. I have experimented with using the `TestHost` API to run the generated project in memory, so it could be run a bit faster but the .NET Core API's for dynamically loading DLL files needs some work which .NET Core 3.0 might solve.

## Link to this sectionWhere To Get It?

You can download the [Boxed.DotnetNewTest](https://www.nuget.org/packages/Boxed.DotnetNewTest/) NuGet package or see the [source code](https://github.com/Dotnet-Boxed/Framework#boxeddotnetnewtest) on GitHub.

## Web Mentions

[What's this?](https://en.wikipedia.org/wiki/Webmention)

### 0 Linked

### 0 Replies

## GitHub Comments

### 1 Comment

[Comment on GitHub](https://github.com/RehanSaeed/rehansaeed.github.io/issues/122)

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Yam](https://camo.githubusercontent.com/fa2ad5a415bf1e3bc2b4c0d539766076e1cec5bcfabac516d452605bd3eb7140/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f37653163653233363964303761343630663766323763356264356636313863323f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/fa2ad5a415bf1e3bc2b4c0d539766076e1cec5bcfabac516d452605bd3eb7140/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f37653163653233363964303761343630663766323763356264356636313863323f733d393626643d6d6d26723d67) **[Yam](https://renetal.com/)** commented on **2020-05-06 07:40:21**

We have been guilty of not covering all the test cases scenarios sometime back when we were in the initial days of the development for the "Cloud Rental Application". But gradually, we have a decent test coverage now. Will give a try to test these cases

```json
{"@context":"https://schema.org","@graph":[{"@id":"https://rehansaeed.com/#website","@type":"WebSite","description":"Software Developer at Microsoft, YouTuber, Open Source Contributor and Blogger","inLanguage":"en-GB","name":"Muhammad Rehan Saeed","url":"https://rehansaeed.com/","author":{"@id":"https://rehansaeed.com/#identity"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://rehansaeed.com/?search={search_term_string}"},"query-input":"required name=search_term_string"}],"publisher":{"@id":"https://rehansaeed.com/#publisher"}},{"@id":"https://rehansaeed.com/unit-testing-dotnet-new-templates/#webpage","@type":"WebPage","dateModified":"2019-08-21T00:00:00+00:00","datePublished":"2019-08-21T00:00:00+00:00","description":"It's difficult to know if your 'dotnet new' based project will work if they have lots of options, in this post I show how to unit test them.","name":"Unit Testing dotnet new Templates","url":"https://rehansaeed.com/unit-testing-dotnet-new-templates/","breadcrumb":{"@id":"https://rehansaeed.com/unit-testing-dotnet-new-templates/#breadcrumb"},"isPartOf":{"@id":"https://rehansaeed.com/#website"},"potentialAction":[{"@type":"ReadAction","target":["https://rehansaeed.com/unit-testing-dotnet-new-templates/"]}]},{"@id":"https://rehansaeed.com/#identity","@type":"Person","name":"Muhammad Rehan Saeed","url":"https://rehansaeed.com/about/","image":{"@id":"https://rehansaeed.com/#/schema/image/1"},"sameAs":["https://github.com/RehanSaeed","https://www.linkedin.com/in/muhammad-rehan-saeed","https://stackoverflow.com/users/1212017/muhammad-rehan-saeed","https://www.youtube.com/c/MuhammadRehanSaeed","https://www.twitch.tv/rehansaeeduk"]},{"@id":"https://rehansaeed.com/#publisher","@type":"Organization","logo":"https://rehansaeed.com/images/schema/Publisher-600x60.png","name":"Muhammad Rehan Saeed","url":"https://rehansaeed.com"},{"@id":"https://rehansaeed.com/unit-testing-dotnet-new-templates/#article","@type":"Article","dateModified":"2019-08-21T00:00:00+00:00","datePublished":"2019-08-21T00:00:00+00:00","description":"It's difficult to know if your 'dotnet new' based project will work if they have lots of options, in this post I show how to unit test them.","headline":"Unit Testing dotnet new Templates","inLanguage":"en-GB","url":"https://rehansaeed.com/unit-testing-dotnet-new-templates/","author":{"@id":"https://rehansaeed.com/#identity"},"image":[{"@type":"ImageObject","url":"https://rehansaeed.com/images/hero/Microsoft-.NET-1366x768.png","caption":"Microsoft .NET","width":"1366","height":"768"}],"isPartOf":{"@id":"https://rehansaeed.com/unit-testing-dotnet-new-templates/#webpage"},"keywords":[".NET","dotnet","dotnet new","NuGet","Project Template"],"mainEntityOfPage":{"@id":"https://rehansaeed.com/unit-testing-dotnet-new-templates/#webpage"},"publisher":{"@id":"https://rehansaeed.com/#publisher"}},{"@id":"https://rehansaeed.com/unit-testing-dotnet-new-templates/#breadcrumb","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","name":"Blog","item":"https://rehansaeed.com/","position":1},{"@type":"ListItem","name":"Unit Testing dotnet new Templates","item":"https://rehansaeed.com/unit-testing-dotnet-new-templates/","position":2}]},{"@id":"https://rehansaeed.com/#/schema/image/1","@type":"ImageObject","contentUrl":"https://rehansaeed.com/images/author/Muhammad-Rehan-Saeed/Logo-512x512.png","inLanguage":"en-GB","url":"https://rehansaeed.com/images/author/Muhammad-Rehan-Saeed/Logo-512x512.png"}]}
```

## Sitemap

See the full [sitemap](https://rehansaeed.com/sitemap.md) for all pages.
