ReSharper test runner still going after tests complete

I’ve been writing some tests and I got this message:

[RIDER LOGO] Unit Test Runner

The process ReSharperTestRunner64:26252 has finished running tests assigned to it, but is still running.

Possible reasons are incorrect asynchronous code or lengthy test resource disposal. If test cleanup is expected to be slow, please extend the wait timout in the Unit Testing options page.

It turns out that because I was setting up an IHost as part of my test (via a WebApplicationFactory) that it was what was causing issues. Normally, it would hang around until the application is told to terminate, but nothing in the tests was telling it to terminate.

The culprit was this line of code:

var factory = new WebApplicationFactory<Startup>().WithWebHostBuilder();

The factory is disposable and I wasn’t calling Dispose() explicitly, or implicitly via a using statement.

The fix to this was simply to wrap the returned WebApplicationFactory<T> in a using block and the test running completed in a timely manner at the end of the tests.

using var factory = new WebApplicationFactory<Startup>()
.WithWebHostBuilder();

or, if by preference, or using an older version of C#:

using (var factory = new WebApplicationFactory<Startup>().WithWebHostBuilder())
{
// do stuff with the factory
}

Although this was running in JetBrains Rider, it uses ReSharper under the hood, so I’m assuming this issue happens with ReSharper running in Visual Studio too.

Join Null Check with Assignment

2017-07-16-join-null-check-with-assignment

I recently wrote some code and asked ReSharper to add a null check for me, which it did. Then it suggested that I could simplify the null check by joining it to the assignment.

Intrigued, I let it.

The code went from this:

public void SetMessage(string message)
{
    if (message == null) throw new ArgumentNullException(nameof(message));
    Message = message;
}

To this:

public void SetMessage(string message)
{
    Message = message ?? throw new ArgumentNullException(nameof(message));
}

So, I assign message to the property Message unless it is null in which case I throw the exception. This is a new feature in C# 7 called a “throw expression”.

At first glance, I thought it would still assign null to Message before throwing the exception, but that’s not what the code looks like underneath.

I got out my trusty dotPeek to see what it actually compiled to. (Don’t worry, I’m not going to show you IL, just what the C# looks like without the syntactic sugar). The result was this:

public void SetMessage(string message)
{
  string str = message;
  if (str == null)
    throw new ArgumentNullException("message");
  this.Message = str;
}

Excellent, it is still doing the null check in advance. So the semantics of what I wrote have not changed. That’s great. I learned something new today.

But…

ReShaper also suggested it in an overloaded version of that function that takes two parameters. And the result was not semantically equivalent. So, be careful. Here’s what happened there. I started with this:

public void SetMessage(string message, string transitionMessage)
{
    if (message == null) throw new ArgumentNullException(nameof(message));
    if (transitionMessage == null) throw new ArgumentNullException(nameof(transitionMessage));

    Message = message;
    TransitionMessage = transitionMessage;
}

Let ReSharper refactor to this:

public void SetMessage(string message, string transitionMessage)
{
    Message = message ?? throw new ArgumentNullException(nameof(message));
    TransitionMessage = transitionMessage ?? throw new ArgumentNullException(nameof(transitionMessage));
}

And, I’m beginning to get a little apprehensive at this point because I think I see a problem. In fact, when I look at it in dotPeek, I can see exactly what the issue is. Here’s the same code with the syntactic sugar removed:

public void SetMessage(string message, string transitionMessage)
{
  string str1 = message;
  if (str1 == null)
    throw new ArgumentNullException("message");
  this.Message = str1;
  string str2 = transitionMessage;
  if (str2 == null)
    throw new ArgumentNullException("transitionMessage");
  this.TransitionMessage = str2;
}

It does the first null check, then assigns to the Message property. Then it does the second null check… And that’s not what I want at all. This method should be an all or nothing proposition. Either both properties are set, or neither are changed and this isn’t the case any more.

Caveat Programmator, as they say in Latin.

Changing the default Assembly/Namespace on an MVC appliction

TL;DR

When getting an error message like this:

Compiler Error Message: CS0246: The type or namespace name 'UI' could not be found (are you missing a using directive or an assembly reference?)

when compiling Razor views after changing the namespace names in your project, check the web.config file in each of the view folders for a line that looks like this:

<add namespace="UI" />

And update it to the correct namespace, e.g.

<add namespace="‹CompanyName›.‹ProjectName›.UI" />

Full story

I guess this is something I’ve not done before, so it caught me out a little.

I’ve recently created a new project and to reduce the file paths I omitted information that is already implied by the parent directory.

So, what I ended up with is a folder called ‹Company Name›/‹ProjectName› and in it a solution with a number of projects named UI or Core and so on. I then added a couple of areas and ran up the application to see that the initial build would work. All okay… Great!

I now have a source code repository that looks like this:

/src
  /‹CompanyName›
    /‹ProjectName›
      /UI
      /Core

In previous projects I’d have the source set out like this:

/src
  /‹CompanyName›.‹ProjectName›.UI
  /‹CompanyName›.‹ProjectName›.Core

While this is nice and flat, it does mean that when you add in thing like C# project files you get lots of duplication in the paths that are created. e.g. /src/‹CompanyName›.‹ProjectName›.Core/‹CompanyName›.‹ProjectName›.Core.csproj

Next up I realised that the namespaces were out as they were defaulting to the name of the C# project file name. So I went into the project settings and changed the default namespace and assembly name so that they’d be fully qualified (just in case we ever take a third party tool with similar names, so we need to ensure they don’t clash in the actual code). I also went around the few code files that had been created so far and ensured their namespaces were consistent. (ReSharper is good at doing this, so you just have to press Alt-Enter on the namespace and it will correct it for you)

I ran the application again and it immediately failed when trying to compile a Razor view with the following error message:

Compiler Error Message: CS0246: The type or namespace name 'UI' could not be found (are you missing a using directive or an assembly reference?)

Looking at the compiler output I could see where it was happening:

Line 25:     using System.Web.Mvc.Html;
Line 26:     using System.Web.Routing;
Line 27:     using UI;
Line 28:     
Line 29: 

However, it took me a little investigation to figure out where that was coming from.

Each Views folder in the application has something like this in it:

<system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.1.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
        <add namespace="UI" />
      </namespaces>
    </pages>
  </system.web.webPages.razor>

There was my old “UI” namespace that had been replaced. It was these settings that were generating the using statements in the Razor precompiled source.

The solution was simple, replace that “UI” namespace with the fully qualified version.

        <add namespace="‹CompanyName›.‹ProjectName›.UI" />

And now the application works!