VB.NET NUnit Testing With Files Made Easy

I’m on my new contract and building a framework for an environmental modelling algorithm originally whipped up with Excel macros. The data for the model exists in an Excel spreadsheet, and the new boss has zero interest in trucking in any form of database technology.

The framework I’m building out currently sucks the data into an ADO.NET DataSet via OLE, then does its data crunching in-memory via LINQ queries and delivers the same results that he’s getting out of VBA/Excel macros in a fraction of the time.

There’s a bunch of unit tests that puts the Excel/DataSet conversion code through its paces. When I was building it, I became dissatisfied with what I was doing with the simple Excel files that I was using with the unit tests. Hardcoding the absolute location of the files really bugged me.

It occurred to me that I might be able to pack the files into the Test assembly, and wherever the assembly was run, it could find a home (like the temporary directory of a hosting filesystem) for the files. Unsurprisingly, this kind of thing has been considered before. I ran across Patrick Caldwell’s blog post nailing how to pack files as resources into an assembly, and then retrieve that resource at runtime from within an NUnit Test. Then I found Scott Hanselman’s post which more elegantly handles stream resources.

Both approaches rely on you adding external files to your unit testing project. Their “Build Action” property is to be set to “Embedded Resource” allowing a file to be embedded within the assembly as a manifest resource. Neither solution quite does what I’m looking for, which is to have a way to do this with Assemblies in general (which neatly solves a problem that plagued me with legacy code in the previous contract). I ended up settling on a utility method that interrogates an assembly for all its resources and dumps them to a specified directory. Here it is:

Public Shared Function UnpackResources(
          ByRef resourceAssembly As Assembly,
          ByRef filePath As String) As String()

    Dim resourcePaths = New List(Of String)

    For Each resource As String In resourceAssembly.GetManifestResourceNames()
      Using resourceStream As Stream = resourceAssembly.GetManifestResourceStream(resource)

        Dim fileName As String = Path.GetFileName(resource)

        ' Not interested in the resource list
        If fileName.EndsWith("resources") Then Continue For

        Dim absoluteFilePath = Path.Combine(filePath, fileName)

        Using outputStream As New FileStream(absoluteFilePath, FileMode.Create)

          FileUtilityCollection.CopyStream(
              resourceStream,
              outputStream
          )
          resourcePaths.Add(absoluteFilePath)

        End Using 'outputStream
      End Using 'resourceStream
    Next

    Return resourcePaths.ToArray()
  End Function

My NUnit test fixture responsible fore all Excel/DataSet conversion testing uses the above method like this:

<TestFixture()>
Public Class TestExcelMediator

  Private AssemblyResourcePaths() As String

  <SetUp()>
  Public Sub Setup()
    AssemblyResourcePaths =
      AssemblyUtiityCollection.UnpackResources(
        [Assembly].GetExecutingAssembly(),
        FileUtilityCollection.GetTempPath()
      )
  End Sub

  <TearDown()>
  Public Sub TearDown()
    For Each path as String in AssemblyResourcePaths
      DeleteFile(path)
    Next For
  End Sub
End Class

On a final note, I discovered this morning that WordPress.com comes with code rendering support. Big hugs to the WordPress crew! You’ve made my morning! 🙂

Advertisements

2 responses to “VB.NET NUnit Testing With Files Made Easy

  1. This code probably doesn’t compile, or maybe you spelled it AssemblyUtiityCollection consistently. Anyway, thanks for sharing !!

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s