Twitter GitHub Facebook Instagram

Daniel Irvine on building software

Resolving assembly resources in tests

1 February 2013

Writing test code is very different from writing production code. The goal is different: tests are meant to be highly readable and malleable. It’s okay to produce code that won’t perform optimally, and it’s okay to produce building blocks that might not be general enough to work under every condition you throw at it. The important thing is you have the building block to produce a multitude of tests easily.

Here’s one example of that--an extension method for C# that means you never have to remember the full path to an embedded resource (including namespace), but instead just a short name. This is great if you’re constantly reorganizing folders and resources as your project grows. It makes your tests less brittle.

 public static class AssemblyExtensions
        public static Stream GetResourceWithNameLike(this Assembly assembly, string nameSubstring)
            var matches = assembly.GetManifestResourceNames().Where(rn =>
            if (matches.Count() == 1)
                return assembly.GetManifestResourceStream(matches.First());

            throw new AmbiguousMatchException(nameSubstring, matches);   

    public class AmbiguousMatchException : Exception
        public AmbiguousMatchException(string name, IEnumerable<string> matches)
            : base(String.Format(Multiple matches were found for the provided name \{0}\:{1}, 
            matches.Aggregate(String.Empty, (m, acc)=>String.Format({0}\n{1}, m, acc))))


That means instead of having to write something like:

using (var stream = asm.GetManifestResourceStream(

You can just write:

using (var stream = asm.GetResourceWithNameLike(A.

The second version is much less brittle than the first.

About the author

Daniel Irvine is a software craftsman at 8th Light, based in London. These days he prefers to code in Clojure and Ruby, despite having been a C++ and C# developer for the majority of his career.

For a longer bio please see To contact Daniel, send a tweet to @d_ir or use the comments section below.

Twitter GitHub Facebook Instagram