State Street Gang
.NET, straight up

Why Mock?

September 1, 2008 14:20 by will

I don't think you can't unit test properly without a mock framework.  Look, I don't have a crap-ton of experience writing unit tests; I've probably written less than 2000 so far.  But from that amount of experience I can definitely say that your code will not be tested as well as it needs to be unless you mock your code dependencies.  Some people aren't clear on why this is true.  This is why I believe you need to mock to test.

The purpose of mocks is to replace dependencies in your code with fake objects that can be controlled during the test process.  It allows you to fully isolate and test the unit of code in question.  These mocks can be instructed on what calls they should expect, and what return values to pass back to the code under test, or even what exceptions to throw.  These assertions can then be checked at the end of the test in order to determine if your code behaved as expected.

The most common question about this process is *why?*.  Why take the effort to replace these dependencies when, IRL, they are part of the code under test?  Wouldn't it make more sense to test everything at once?

The reason is because a unit test should focus on a specific unit of code; a unit most commonly meaning a specific execution path through a single method.  If your test calls other methods of other objects, your test isn't about the specific unit in question; it is testing the interaction between two objects within your codebase.  That's not a unit test; its an integration test.  While integration tests are valid and useful, they may result in false positives in your tests.  An object may not behave as expected, due to its code being buggy, which results in a false positive in your test.  Mocks also allow you to test code in ways that would normally be hard, or even impossible, to do using the real dependencies.

In order to remove the chances of this from happening, you replace this dependency with a mock object.  You then instruct the mock to expect certain calls and return certain results, or even to throw exceptions which may be hard, if not impossible, to simulate with production code.  You can then fully exercise the method under test, hitting all the code paths in a structured way that can be reviewed for correctness.  And, unless you do this, your code isn't tested.


Tags:
Categories: Testing
Actions: E-mail | Permalink | Comments (2) | Comment RSSRSS comment feed

MoQs RoX

June 27, 2008 11:07 by Will

After the big refactor last iteration we're working on the unit tests.  One of the things I wanted to get done was to replace all our lousy stubs (none of which would compile now after the refactor) with a true mock framework.  When considering framework candidates, I had three requirements:  First, it had to be easy to learn and use.  Second, it had to be fully compatible with .NET 3.5 (i.e., using expression trees instead of strings to set expectations).  Third, it had to be free. 

The two candidates I chose are Rhino Mocks 3.5 and MoQ 2.5.  Because MoQ is fully documented (Rhino's 3.5 is a massive change, so all of the documentation out there for the previous versions is useless) I went with MoQ.  I still have Rhino as a reference just in case MoQ can't handle something.  I haven't found one yet.

More...

Tags:
Categories: MoQ | Testing
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

InternalsVisibleToAttribute and Strong Named Assemblies Step by Step

April 9, 2008 12:17 by Will

One of the hassles with testing is that best practices and OO design often makes it very difficult to thoroughly test your code.  We should be marking classes internal to our assemblies unless we specifically wish them to be part of the public API of our DLL's.  This means to test these internal classes we have to use proxy classes that can instantiate and invoke members of these internal classes via reflection.  Visual Studio provides for some auto-generated code for this, but it can be a bit unwieldy and is not available in all versions of VS.  It would be easier if we could specify a test assembly as having access to all these internal classes.

Another case where we might want to make our internal classes available to specific outside callers is for security purposes.  If we don't want anyone but ourselves to use a specific DLL, we would want to mark all classes internal to the DLL and specify only those assemblies with our strong name have access to them.

The InternalsVisibleToAttribute allows us to do this.  According to the documentation, the syntax is pretty easy:

[assembly: InternalsVisibleTo("MyTestsLol")]

This would allow assembly MyTestsLol.DLL access to the internal classes of the assembly where this attribute is located.  And this works great.  For unsigned assemblies only.  When you sign the assembly you wish to mark with this attribute, things get more complex.

Lets say you have two assemblies, My.DLL and MyTestsLol.DLL.  You add the above attribute to the AssemblyInfo.cs file within the My.DLL project.  Everything works great; you can access and test all internal classes in My from within MyTestsLol.  But you're moving to a production oriented environment and you decide that you should be signing your assemblies, because you've read that's what professional .NET developers do.  So you sign My.DLL and build the project:

Friend assembly reference 'MyTestsLol' is invalid. Strong-name signed assemblies must specify a public key in their InternalsVisibleTo declarations.

Now you're screwed.  And if you Google this, you'll still be screwed because most of the information about InternalsVisibleTo and strong named assemblies is either wrong or too cryptic to understand.  If you find yourself at this point, here is the step-by-step procedure how to get this working again.

Gimme three steps to fix

image First, you will need to sign every assembly you wish to grant access to your internals.  Open up the properties editor for the assembly you wish to give access to, in this case MyTestsLol.DLL, and select the Signing tab.

I'd suggest creating a new, throw-away key pair for test assemblies.  For assemblies you are going to distribute you should use your regular key pair.

Second, you must extract the public key from the public/private key pair, then display the public key.  This is a two-part process that is necessary in order to get the correctly encoded version of the public key. 

Open the Visual Studio command prompt (All Programs -> Visual Studio 2005/8 -> Visual Studio Tools).  Browse to the directory where the new public/private key pair is located.  At the prompt, enter the following command (the name of the key pair (.snk) may be different if you chose a different name for the strong name key file):

sn -p fortestsonly.snk publickey.pub

This creates a file, called publickey.pub, that contains the public key portion of the public/private key pair in binary format.  Next, you need to view the public key in an encoded format (I believe its Base64) that you can use.  Do this via the following command:

sn -tp publickey.pub

This displays both the full public key and the public key token, which is a much smaller hash of the full public key.  You'll need the full public key (the token will not work), so select it and copy it out of the console.  Consoles suck, so you'll have to remove all the newline's when you paste it into your assembly. 

Finally, adjust your InternalsVisibleTo argument to add the public key (the public key should reside on a single line and be roughly three hundred something characters long):

[assembly: InternalsVisibleTo("MyTestsLol, 
    PublicKey=0024...8db5")]

The ellipsis is just to keep the key from blowing up my blog's layout. 

This will now work, and you can reference internal types from the MyTestsLol assembly.  Unfortunately, there isn't an equivalent attribute you can place on a type to allow its internals be visible to another type or another assembly, which would have made unit testing private methods a snap.  I'm not sure exactly why we don't have this kind of facility in the .NET platform.  Maybe in 4? 

kick it on DotNetKicks.com
Tags:
Categories: CLR | Testing | Tips
Actions: E-mail | Permalink | Comments (4) | Comment RSSRSS comment feed

Can't save results of the run since ResultFilePath is null.

February 21, 2008 11:12 by will

I've been hit by this lovely error a number of times over the past year when attempting to run unit tests in Visual Studio 2005.  I always end up searching for the answer, encountering the fifty or so different "solutions" that fail horribly.  So now I save it here.

The fix is to reset your environment in Visual Studio.  You can do this by opening a Visual Studio Command Prompt (MS Visual Studio 2005 -> Visual Studio Tools from the start menu) and run the following command (PLEASE READ ON prior to running this!  Important stuff comes later!):

devenv /resetuserdata

This brings Visual Studio back to the primordial stage.  Unfortunately, you lose all your settings.  That includes all your tricky VS fonts and colors customizations.  You won't lose your Add-ins, however.  So if you want to save and then reload all your UI customizations, you'd better save them first. 

For some info about saving color and font settings, you can check out this post over at CodingHorror.


Tags:
Categories: Debug | Testing | Tips
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

C# Next: How about some integral testing support?

January 4, 2008 15:14 by Will

So I'm sitting here at work, reviewing mock frameworks like Rhino Mocks and TypeMock for use in our unit tests, when an actual useful idea for the next verison of the CLR pops into my head. 

One of the problems with unit testing is that the requirements of the tests are often polar opposite of object oriented best practices.  Some of these, like data hiding, are relatively easy to overcome in .NET using features such as reflection.  Others aren't so easy to deal with. Im in ur code mockin ur objex

For instance, say you have a sealed class in your application that doesn't implement an interface.  How do you mock that class?  The TL;DR answer to that question is that you can't do it without rewriting your class or using expensive and complicated testing tools.  The second option is often out of the question with small shops like mine.  The first option is viable, but complicates your code and can end up breaking some OO principles or best practices to do so. 

What would be real slick is if the CLR team provided some first class support for testing.  For the example above, it could be the ability to override sealed to allow classes to be extended for mocking.  Another feature might be a SuperNew, that allows child classes to override base class methods even when the object is cast to the base class type.  Yet another may be allowing extension methods to replace methods in an object.  That might be the simplest way of all to mock an object.  Combine the replacement methods with classes designed to record method arguments and play back return values and unit testing becomes a breeze.

These changes, of course, can be a security and stability risk.  But so can using reflection to manipulate private object fields.  But there isn't any reason why these facilities can't be turned on and off via, for example, compiler switches.  In this case, it could be as easy to control as setting a flag within a configuration (say Debug). 

Ah, well, we can dream, can't we?  Perhaps the CLR team will concentrate on some other important additions to the platform, like cupholders and vibrating, heated seats. 


Tags:
Categories: Testing
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed