Showing posts with label .Net. Show all posts
Showing posts with label .Net. Show all posts

Wednesday, April 30, 2014

Making Moq Better...

TL;DR;  (Too Long Don't Read)

I wrote an extension for Moq to assert that no methods are called on a mock object.

Moq is great ...

Moq is my favorite mocking framework for C#, but it's not perfect.

I like it because it supports test Spies (to use Martin Fowlers terms).

Test Spies remember interactions, so you can assert on them at the end of the test instead of setting up your expectations at the beginning of the test. Some people don't like this as your feedback comes after the faulty code has been executed, instead of being at the point the unexpected interaction occurs, so you don't have the same stack trace, What it does, however, is allow you to follow the Arrange, Act, Assert pattern for test construction. This in turn allows you to strictly limit the focus of your tests, making them less brittle and more intention revealing.

But ...

If you want to assert that no interactions occurred with an object, this standard way of doing this in Moq is to use a "strict" mock. A Strict mock will throw exceptions when a method you didn't explicitly set up is called.

Strict mode is set at object construction which is typically in your setup method, so can't be changed on a per test basis. This means all tests make this interaction implicit assertion even the ones where the focus of the test isn't on these interactions.

Even worse, say you "setup" some default behaviour for your Stub object, Now if you want to know that no methods are called on a specific test, then you have to explicitly "verify" each method individually to assert it's not called. This makes tests brittle. If you add a new method to the object you have to add that methods to any test that was asserting that no interactions occurred.

Extension Methods To the Rescue!


To help with this I have written an extension method to verify no methods are called on an object.

This useful, but is only a step in the right direction. Ideally you would be able to specify all the interactions you do want to occur, and finish by saying "and nothing else".

https://gist.github.com/NigelThorne/96badd3ba9a18d084cd8


Wednesday, August 27, 2008

Running a .NET Executable from a Network Drive

Rob Smyth is developing NUnitGridRunner, a tool to run nunit.console on several machines at once.

As any application under test grows, so does the number of UATs. Rob's project aims to allow us to scale the running of UATs by adding network boxes.

What does this have to do with Running .NET executables on network drives?

Well, Rob needs to distribute the latest version of the assemblies and tests to each machine so they could run the tests. It's simpler if they just all run from a network path. ,However .NET got in the way.

1/2 a day later we had a solution.

If you run nunit-console.exe from a command shell accessing it from the network drive, you get the following error.


Unhandled Exception: System.Security.SecurityException: That assembly does not allow partially trusted callers.
at System.Security.CodeAccessSecurityEngine.ThrowSecurityException(Assembly asm, PermissionSet granted, PermissionSet refused, Runti
ityAction action, Object demand, IPermission permThatFailed)
at NUnit.ConsoleRunner.Class1.Main(String[] args)
The action that failed was:
LinkDemand
The assembly or AppDomain that failed was:
nunit-console, Version=2.4.6.0, Culture=neutral, PublicKeyToken=null
The method that caused the failure was:
Int32 Main(System.String[])
The Zone of the assembly that failed was:
Internet
The Url of the assembly that failed was:
file://aumelw021202/GridRunnerSandPit/AUMELW061120/nunit-console.exe


This is due to .NET's permissions system. There are lots of articles online telling you how to recompile your exe to make it run. This is a 3rd party exe though, so I don't want to have to recompile it. That would mean that each time I want to upgrade I would have to do extra steps.

Anyway.. here is the solution I used.

First I changed the Zone that .Net things the network drive belongs to.


Control Panel >> Internet Options >> Security >> Local Intranet >> Click Sites... >> Advanced...
in 'Add this Web site to the zone:' enter the network path.. and click Add
eg. \\MyNetworkMachine\DirectoryContainingExe

You can test this worked by running the executable again from a dos prompt...

The Zone of the assembly that failed was:
Intranet


Notice it moved to Intranet.

Now all you have to do is tell .NET to trust executables in that zone.


Control Panel >> Administrative Tools >> .NET Framework 2.0 Configuration >> Configure Code Access Security Policy >> Adjust Zone Security >> Next >>

Click "Local Intranet" and slide the slider up to Full. Then click Next a couple to of times.

You can now run the executable... TADA!

What you've done is allow .NET assemblies in the local intranet to be executable on your machines. If this represents a security risk for your machines then this is not the right solution for you.

For us it works great.

Monday, July 28, 2008

Removing Redundant code with NDepend

As we refactor our code, some design changes make some existing code redundant. When you have unit tests on all your code you can't find this using coverage. So finding this redundant code can be tricky.

What you need is a tool that can analyze your code base. The best I have found for .Net is NDepend.

NDepend provides a query language for code.

I started a project and added all assemblies except the test ones. I then ran the query :
SELECT TYPES WHERE TypeCa == 0

TypeCa refers to the 'Afferent Coupling' of the type.. ie. how many other types refer to this one.

This found 40 files I could delete.

I used Resharper to double check each one was not used (except in tests).

I got a couple of false positives with types I am only using to pass as type parameters to generic classes. This is the only thing stopping me adding this check as part of our build script.

Finding all those classes by hand would have taken much longer, so...

Works for us!

Tuesday, June 17, 2008

Mocking Generic Method with NMock2 (part2)

Well although this feature has been mentioned on the web it doesn't seen to exist in any version of NMock2 I can find. With a bit of digging I worked out how to implement it myself.

You can download the assembly from NMock2Extensions try it out, or download the source from svn.

Here's an example of using it...


Stub.On(childScope)
.Method(new GenericMethodMatcher("Get", typeof(IControl)))
.Will(Return.Value(control));

Expect.Once.On(childScope)
.Method(new GenericMethodMatcher("Get",typeof(IDocument)))
.Will(Return.Value(NewMock()));


As you can see, you can Stub or Mock on the same method with different generic types and they are handled differently, as you would expect.

Happy Mocking

Monday, November 19, 2007

NCoverCop trunk... for coverage

If you grab NCoverCop from svn you can check out a couple of improvements.


  • Refactoring Allowed.. If you delete tested code that is no longer needed, then this will unfortunately have the side effect of dropping your coverage percentage. NCoverCop allows for this by checking the number of untested lines. If it has not increased then the build is passes as you didn't make things worse.

  • Coverage Differences are displayed when a build fails to give you an idea of the lines in the file that have become uncovered, or been added without test.

  • sectionOfFilePathToCompareRegex allows you to specify a section of the document paths in the NCoverResults.xml files to ignore when comparing the files. This allows you to compare the build's file with your local one even if your trunk paths differ.


          coverageFile="${ncover.output.filename}"
minCoveragePercentage="59"
previousCoverageFile="${ncover.backup.filename}"
autoUpdate="${environment::get-machine-name() == debug.buildbox.name}"
sectionOfFilePathToCompareRegex="trunk.*"
/>


E.g. "trunk.*" (as above) will truncate "C:/something/trunk/somedir/file.cs" to "trunk/somedir/file.cs" when comparing with another results file.


Let me know if you find NCoverCop useful.


Note: Big big thanks to VarianInc for allowing me to do some work on NCoverCop on their dime. They have introduced a policy of using opensource code wherever they can, and contributing back to the community.

Varian (Melbourne) are by far the most agile company I have worked for to date. I highly recommend anyone that is keen to be part of a well functioning agile .Net team to get in contact with them. Email me and I'll forward your details if you like.

Thursday, September 13, 2007

Tip#3: Extend your mocking framework

Currently I am using NMock2 in my C# development. I have however made a few extensions to allow me to test some edge cases. Due to the clean design of NMock extending it is really easy.

IAction


A normal use of NMock looks like this:

Expect.Once.On(someObject).Method("methodName").WithAnyArguments().Will(Return.Value("value"));


In this statement the 'Return.Value' method returns an object that implements the IAction interface. The job of this object is to perform some action at the point the expectation matches. In this example the effect is to set the return value of the method to a known string.

However... any class implementing the IAction interface can be passed to the 'Will' method, so if you have some special need to execute code at the point the method is matched, then here is a great place to put it.

Here is an example...
[Test]
public void Move_Sleeps_UntilUpdatedWithTrue
{
Expect.Once.On(sleeper).Method("Sleep").Will(Execute.Delegate(delegate { mono.Update(false); }));
Expect.Once.On(sleeper).Method("Sleep").Will(Execute.Delegate(delegate { mono.Update(false); }));
Expect.Once.On(sleeper).Method("Sleep").Will(Execute.Delegate(delegate { mono.Update(true); }));
mono.Move(120);
}


Here I have used an IAction class that invokes a delegate at the point your expectation is met. In this case I am using it to test a piece of code that repeatedly sleeps (using a sleeper service) until the object is updated with true. I am intercepting the call to sleep and instead taking the opportunity to update the object.

Here is the code that makes that possible.
public class Execute : IAction
{
public delegate void DelegateAction();
private readonly DelegateAction action;

public static IAction Delegate(DelegateAction action)
{return new Execute(action);}

private Execute(DelegateAction action)
{this.action = action;}

public void Invoke(Invocation invocation)
{action();}

public void DescribeTo(TextWriter writer)
{}
}
So in way of explanation: the invoke method is want gets called when the expectation is met. It just invokes the delegate the 'Execute' object was constructed with. The rest is just static methods to allow you to say Execute.Delegate(...) rather than new Execute(...)

Next post I'll explain how I test firing events using another extension to NMock.

Tuesday, August 14, 2007

Tip:#2 Smell: Duplicate Tests Indicate a Missing Class

Smell: A class with two public methods on it, both perform the same functionality, or one is a subset of the other. The existence of a private method is a good indication of this.

To fully test these public methods you have to repeat a bunch of tests. There has to be a lazier simpler solution.

Recently I have been getting this smell a lot using MVC in a .Net winforms app.

.Net forms are hard to unit test. It is therefore helpful to keep your Views as thin as possible. Just use them to expose the form fields as a bunch of properties and to catch events and call the corresponding method on the controller. This moves the logic to the Controller where it is far more testable.

This can however lead to methods on the controller like "OnStartButtonClicked" and "OnStartMenuItemSelected". Both are going to perform the same actions. Both are going to need the same set of tests.

The solution is simple. Use the 'Extract Class' refactoring to pull the private method out to another class and use Dependency Injection to pass an instance of this new class back to the original class.

Following this above advice though you end up with another object. In my experience this split makes a lot of sense. I call this new class a Service. I rename the new thinner Controller to Presenter which better resembles it's remaining responsibilities.

(Note: I've read a few things on the differences between MVC and MVP, but I don't really get it. What I have here may be what is meant by the naming. Either way I like this design better.)

I'm really liking the new code. The view is really thin. The presenter translates UI events to service calls, and knows which views to update when the domain changes.

A piece of advice Steve Hayes often gives is "Design your UI layer so you could replace it with a command line and everything would keep working". I have struggled to do this with .Net, even with MVC. Having this new split however I can see keeping the Service and Model layers and replacing the UI would be easy.

So... Look out for duplicates tests... get lazy and write better code!

Friday, July 06, 2007

Tip:#1 Testing Events in C#

If you have a class that causes a .Net event to fire. When writing a test for the event, you can add a handler to the event that sets a flag that you then assert on in your code. Using normal delegates means the variable would need to be a class member and get initialized in Setup. Use of anonymous delegates cleans this up nicely.

[Test]
public void TriggerEvent_CausesEventThatFiresToFire()
{
Customer customer = new Customer("Ben");
string changedPropertyName = null;

customer.PropertyChanged += delegate(object sender, PropertyChangedEventArgs args)
{changedPropertyName = args.PropertyName;};

customer.Name = "Kate";

Assert.AreEqual("Kate",changedPropertyName);
}

GitHub Projects