Thursday, January 15, 2009

NUnit error - Could not load type 'custom.namespace' from assembly 'System.Web...

I was recently having some issues using NUnit to test my code when the code was using the .net membership profile provider.  Scott Davis summed it up nicely:

I've implemented it easily in my site and it works great, but have you been able to unit test it?  On my first attempt, the inherited "Create" method returned a DefaultProfile object, which caused a casting failure.  I figured out that the Unit Tests were not using the web.config file to see the custom Profile Provider I configured, then I figured out you need to copy the web.config to the unit test project, and rename it to app.config.  However now I get the error.  

"Test method TestMyProject.UserControllerTest.CreateNewUserTest threw exception:  System.TypeLoadException: Could not load type 'MyRootNamespace.Profile.UserProfile' from assembly 'System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.."

I don't know why it is not looking the DLL that contains my custom "UserProfile" class.  Any ideas?  It works in my website, but not in the Unit Test.  The UnitTest project references the project containing the Profile class.  I'm using VS2008 built-in Unit Testing.

A little further down I found a link to a forum where the answer was eventually discovered from here and explained a little further:
My config file was something like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
    <add name="MeanWormConnectionString" connectionString="Server=localhost;Database=MeanWormDB;Trusted_Connection=true"/>
  </connectionStrings>

  <system.web>

    <membership defaultProvider="MeanWormMembershipProvider">
      <providers>
        <remove name="AspNetSqlMembershipProvider"/>
        
          <add applicationName="MeanWorm" requiresQuestionAndAnswer="false"
            requiresUniqueEmail="true" minRequiredNonalphanumericCharacters="0"
            enablePasswordReset="true" passwordFormat="Hashed" connectionStringName="MeanWormConnectionString"
            name="MeanWormMembershipProvider" type="MeanWorm.Domain.Providers.MeanWormMembershipProvider" />
        
      </providers>
    </membership>
  </system.web>
  
</configuration>

 

 His config file was this:

 

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
    <add name="MeanWormConnectionString" connectionString="Server=localhost;Database=MeanWormDB;Trusted_Connection=true"/>
  </connectionStrings>

  <system.web>

    <membership defaultProvider="MeanWormMembershipProvider">
      <providers>
        <remove name="AspNetSqlMembershipProvider"/>
        
          <add applicationName="MeanWorm" requiresQuestionAndAnswer="false"
            requiresUniqueEmail="true" minRequiredNonalphanumericCharacters="0"
            enablePasswordReset="true" passwordFormat="Hashed" connectionStringName="MeanWormConnectionString"
            name="MeanWormMembershipProvider" type="MeanWorm.Domain.Providers.MeanWormMembershipProvider,MeanWorm.Domain" />
        
      </providers>
    </membership>
  </system.web>
  
</configuration>

 

 

Can you spot the difference? It's in the "type" attribute of the add provider tag. If you have a custom provider and do not specify the partial assembly name to find the class in, nunit flips out and tries to load the class from the default assembly, which is System.Web.dll.

If you want more information on how the type attribute works check out this post.

3 comments:

pu43x said...

Thanks for this, I was trying to call a customer membership provider from a console app I wrote, and this solved my issue.

Thanks again for sharing.

Morgan said...

Thanks! I was banging my head around on this issue for the better part of a day.

Dustin said...

Thanks so much for this post. I have been pulling my hair out over this one for the past 4 hours.