This happens to me frequently: many of the assemblies I write require
configuration in the configuration file. So, I'll write a portion of
my unit tests to deserialize an assembly and assert that it received
the designated settings from the config. I also generally deploy
signed assemblies (so that they can go into the GAC, etc); most of the
time, if I sign an assembly and then run my unit tests, the portion of
the unit tests testing my assembly loads from the config fail. Why?
Because I'm using no longer using a valid fully-qualified assembly name
in my test config. Typically, my test configs will look something like
this:
<configuration>
<configSections>
<section name="MySection" type="Brad.Tests.ConfigSections.MySection, Brad.Tests.ConfigSections, Version=1.0.0.0, PublicKeyToken=null"/>
</configSections>
<MySection someSetting="hello cleveland" />
</configuration>
However, when I sign the Brad.Tests.ConfigSections assembly, the
PublicKeyToken value will no longer be null and my test will fail with
a configuration exception.
So, why am I
bringing all of this up? Well, the other day, I ran a bunch of tests
written by another developer against an assembly I knew was signed. I
figured some of the tests would fail--I just wanted to see which ones.
Interestingly, all passed including the ones written to work with the
config file. So, either the tests were written to work only with a
signed assembly (probably not the best approach for a unit test) or
something else was afoot. When I looked at the test config, I saw
something like this:
<configuration>
<configSections>
<section name="MySection" type="Brad.Tests.ConfigSections.MySection, Brad.Tests.ConfigSections, Version=1.0.0.0"/>
</configSections>
<MySection someSetting="hello cleveland" />
</configuration>
Hmm. The developer used a truncated version of the assembly name. I
didn't know you could do that. So, let's try some experiments:
Configuration used: "Brad.Tests.ConfigSections.MySection, Brad.Tests.ConfigSections"
Unsigned assembly: works
Signed assembly: works
Configuration used: "Brad.Tests.ConfigSections.MySection, Brad.Tests.ConfigSections, Version=1.0.0.0"
Unsigned assembly: works
Signed assembly: works
Configuration used: "Brad.Tests.ConfigSections.MySection, Brad.Tests.ConfigSections, Version=1.0.0.0, PublicKeyToken=null"
Unsigned assembly: works
Signed assembly: fails
Configuration
used: "Brad.Tests.ConfigSections.MySection, Brad.Tests.ConfigSections,
Version=1.0.0.0, PublicKeyToken=f479d21bc132bee6"
Unsigned assembly: fails
Signed assembly: works
Let's try something a little different. Keeping my version at 1.0.0.0, let's this configuration and see what happens:
Configuration used: "Brad.Tests.ConfigSections.MySection, Brad.Tests.ConfigSections, Version=2.0.0.0"
Unsigned assembly: works
Signed assembly: fails
Hmm.
That was interesting: when an assembly is unsigned, the version seems
superfluous. However, when an assembly is signed, the version
designation becomes important.
How about this: bump my assembly's version up to 2.0.0.0 and try this configuration:
Configuration used: "Brad.Tests.ConfigSections.MySection, Brad.Tests.ConfigSections, Version=1.0.0.0"
Unsigned assembly: works (guess we still don't care about version number)
Signed assembly: fails
Sidebar on signing assemblies