Showing posts with label C#. Show all posts
Showing posts with label C#. 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


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.

Unveiling NCoverCop

Duncan Bayne (who I have the pleasure of working with at the moment) had the idea of writing a small exe to parse an NCoverResults file and fail a build if the coverage drops below a set threshold. I loved it... and decided to up the ante.


From that seed I have built NCoverCop.

NCoverCop is a custom NAnt task that not only fails your build if your coverage drops, but lifts the threshold each time a new build passes with a higher threshold.

It works by keeping a copy of the best coverage file.

Here's how I use it..


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


  • coverageFile is the location of the NCoverResults.xml file you want to compare.

  • previousCoverageFile is the file that will be overwitten if a successful build beats the current threshold.

  • minCoveragePercentage is used when you don't have a previousCoverageFile yet or the specified percentage is higher than that of the previousCoverageFile.

  • autoUpdate can be turned off so the previousCoverageFile doesn't get updated in a passing build.[defaults to on]



Here are a few tips...

We have the previousCoverageFile in a location that is visible on the network and referenced in the build file through it's network address. Coupled with being able to turn autoUpdate off for everyone except the build machine means that you can run ncoverCop locally and see if you are going to break the build before you check in.

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.

GitHub Projects