Sunday, September 28, 2014

xUnit Theory Data from Configuration

I've said it before and I'll say it again, I love xUnit!

In particular, I love xUnits support for data driven tests. It offers several different options for ways to power a data driven unit test right out of the box. Best of all, xUnit allows for easy extensibility.

I have written some simple extensions for xUnit that allow you to power your data driven tests from your configuration file. Not only that, but it allows you to optionally provide default data using inline attributes when no configuration is available.

Sample Config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="testData" 
type="Xunit.Extensions.Configuration.TestDataSection,xunit.extensions.config"/>
  </configSections>
  <testData>
    <tests>
      <add name="Demo.Tests.Basic">
        <data>
          <add index="0" p0="1" />
        </data>
      </add>
      <add name="Demo.Tests.FromConfig">
        <data>
          <add index="0" p0="4" />
        </data>
      </add>
    </tests>
  </testData>
</configuration>

Sample Tests

namespace Demo
{
    public class Tests
    {
        [Theory]
        [ConfigData]
        public void Basic(int i)
        {
            // This theory data comes from the config file.
            Assert.Equal(1, i);
        }
 
        [Theory]
        [ConfigOrInlineData(2)]
        public void FromInline(int i)
        {
            // This theory data comes from the attribute.
            Assert.Equal(2, i);
        }
 
        [Theory]
        [ConfigOrInlineData(3)]
        public void FromConfig(int i)
        {
            // This theory data comes from the config file
            // instead of the attribute.
            Assert.Equal(4, i);
        }
    }
}

Enjoy,
Tom

Saturday, September 20, 2014

await await Task.WhenAny

The await operator in C# automatically unwraps faulted tasks and rethrows their exceptions. You can await the completion of multiple tasks by using Task.WhenAll, and then if any of those tasks are faulted all of their exceptions will aggregated and rethrown in a single exception by the await.

However, Task.WhenAny does not work the same way as Task.WhenAll. Task.WhenAny returns an awaitable Task<Task> where the child Task represents whichever Task completed first. A key difference being that the container task will not throw when awaited!

If an exception occurs inside of a Task.WhenAny, you can automatically rethrow the exception by doing (and I realize how weird this sounds) await await Task.WhenAny

Sample Tests

[Fact]
public async Task AwaitWhenAnyWait()
{
    var t1 = Task.Run(async () =>
    {
        await Task.Delay(100);
 
        throw new InvalidOperationException();
    });
 
    // This await will NOT throw.
    var whenAny = await Task.WhenAny(t1);
 
    Assert.True(whenAny.IsFaulted);
    Assert.NotNull(whenAny.Exception);
    Assert.IsType<InvalidOperationException>(whenAny.Exception.InnerException);
}
 
[Fact]
public async Task AwaitWhenAll()
{
    var t1 = Task.Run(async () =>
    {
        await Task.Delay(100);
 
        throw new InvalidOperationException();
    });
 
    try
    {
        // This await WILL throw.
        await Task.WhenAll(t1);
 
        throw new AssertException();
    }
    catch (InvalidOperationException)
    {
    }
}
 
[Fact]
public async Task AwaitAwaitWhenAny()
{
    var t1 = Task.Run(async () =>
    {
        await Task.Delay(100);
 
        throw new InvalidOperationException();
    });
 
    try
    {
        // This await await WILL throw.
        await await Task.WhenAny(t1);
 
        throw new AssertException();
    }
    catch (InvalidOperationException)
    {
    }
}

Enjoy,
Tom

Monday, September 15, 2014

Possible Multiple Enumeration Warning

Someone recently asked me what the "Possible Multiple Enumeration" warning means. The IEnumerable interface only exposes a single method, GetEnumerator. This means that every and every time we want to traverse the enumerable we have to start at the beginning and iterate the entire enumeration again.

public interface IEnumerable<out T> : IEnumerable
{
    IEnumerator<T> GetEnumerator();
}
 
public interface IEnumerable
{
    IEnumerator GetEnumerator();
}

Whenever you see the Possible Multiple Enumeration warning the compiler is trying to tell you that your code my be sub-optimal at run time because it will have to completely traverse the enumerable multiple times.

More importantly, the compiler can not be sure what that enumeration will entail!

Why could that be bad?

With a collection we know what the contents and implementation of the enumerable are, and we are able to know the run time implications of iteration over that collection. However an IEnumerable is an abstraction and not a guaranteed implementation, meaning that it may represent a very inefficient enumeration.

For example, an object relational mapping (ORM) framework may expose an IEnumerable that loads it's items from a database on each iteration. Other IEnumerables may be computing complex and CPU intensive operations during iteration. The simple fact is that when your code is iterating over an IEnumerable you just can not be sure what is actually happening behind the interface.

This is not necessarily a bad thing, but that uncertainty does merit a warning.

Thursday, September 11, 2014

Decompile Methods with ReSharper

ReSharper is an amazing tool that .NET developers should never be without. One of my favorite features that if offers is build in support for decompiling methods when navigating to source. Enabling this option will literally allow you to view external source code simply by going to definition.

To enable this option, go to...

  1. Open the "ReSharper" Drop Down
  2. Select "Options"
  3. Expand "Tools"
  4. Select "External Sources"
  5. Select "Navigation to Sources"
  6. Check "Decompile methods"
  7. Save, and you're done!

Would you like to do this outside of Visual Studio as well? Check out JetBrains FREE decompiler tool, dotPeek.

Enjoy,
Tom

Sunday, August 31, 2014

Three steps to wire up your IOC container.

How can you dynamically and flexibly wire up your inversion of control container? Here are three easy steps to consider:

  1. Reflection
  2. Explicit
  3. Configuration

First, use reflection to help wire up your boiler plate or dynamic dependencies. Second, explicitly register and customize any additional dependencies that your application needs Third, use configuration last to dynamically override any of your previous settings, allowing you to make changes to your application in a live environment without having to rebuild or deploy.

Sample Code

Microsoft's Unity offers a last in win container, so if you follow the steps above in order you will have a very flexible configuration for your container!

Sunday, August 24, 2014

xUnit Console Runner - Filter by Test Name

You can now filter by test name with the xUnit Console Runner.

Sample Code

namespace DemoProject
{
    public class ExampleTests
    {
        [Fact]
        public void HelloWorld()
        {
            Assert.True(true);
        }
 
        [Fact]
        public void GoodnightMoon()
        {
            Assert.True(false);
        }
    }
}

Sample Command Line

C:\>xunit.console.exe DemoProject.dll -testName "DemoProject.ExampleTests.HelloWorld"
xUnit.net console test runner (64-bit .NET 4.0.30319.18449)
Copyright (C) 2014 Outercurve Foundation.

Starting:  DemoProject.dll
Finished: DemoProject.dll

=== TEST EXECUTION SUMMARY ===
   DemoProject.dll  Total: 1, Failed: 0, Skipped: 0, Time: 0.276s, Errors: 0

Enjoy,
Tom

Saturday, August 16, 2014

System.Net.CredentialCache supports Digest Auth

In my last post I talked about implementing Digest Authentication in WebAPI. That was a server side implementation, but how do you make requests to that server? Good news: .NET's built in CredentialCache supports Digest Authentication!

PreAuthenticate

Be sure to enable PreAuthenticate, otherwise each request will require a new digest token have to make an additional two requests to get it! Do not worry, the request will not send your credentials without having a token first.

PreAuthenticate = false

PreAuthenticate = true

Real Time Web Analytics