A collection of learnings and opinions.

Thursday, September 24, 2009

Mocking expectations on Property setters with MoQ

When mocking out your classes using the fabulous MoQ mocking-framework you may sometimes need to mock out an expectation that a property on your mocked object should be set.

It took me some time to figure out how to do this. The documentation on the MoQ quickstart wiki says to use the following pattern:

// expects an invocation to set the value to "foo"
mock.SetupSet(foo => foo.Name = "foo");


Well, I tried this with an object:

public class SomeClass {
public string Something { get; set; }
}

[Test]
public void PropertySetupOnMock() {
const string someString = "Should be set";
var mocker = new Mock<SomeClass>();

mocker.SetupSet(x => x.Something = someString); //exception here
mocker.Object.Something = someString;
mocker.VerifySet(x => x.Something);
}

This only gave me an error on the line with the SetupSet:
System.ArgumentException: Invalid expectation on a non-overridable member.

Well, that's strange. After some looking around it turns out that MoQ does its magic by extending the class that's being mocked. It cannot extend non-virtual properties, so this Something property cannot be extended and thus cannot be Setup.
What can be done about this? The easiest immediate solution would be to mark the property virtual, like so:

public class SomeClass {
public virtual string Something { get; set; }
}

But do we really want to decorate every property on the objects as virtual? Not really. A better solution is to push the property up to an interface and mock that interface instead, like so:

public interface IWithProperty {
public string Something { get; set; }
}

public class SomeClass : IWithProperty {
public string Something { get; set; }
}

[Test]
public void PropertySetupOnInterfaceMock() {
const string someString = "Should be set";
var mocker = new Mock<IWithProperty>();

mocker.SetupSet(x => x.Something = someString); //no exception here
mocker.Object.Something = someString;
mocker.VerifySet(x => x.Something);
}

Thus allowing me to mock it out and test that the property setter was indeed called. Yay!
If anyone has any better ways of doing this I'd love to hear from you!

Tuesday, February 10, 2009

Listing the properties of an object

Sometimes you just want to print out the state of some reasonably rich object (for logging or GUI mock-up or whatever). This code gives you a PropertyGetter class with two easy-to-use static methods. listProperties returns a name: value string listing of the properties on the input object, for easy logging.

If you want the object's properties as a list of properties you can get that as well.

NB: This simple class does not recurse through complex objects, so you will only ever get the top-level of a property.

Code:

using System.Collections.Generic;
using System.Reflection;
using System.Text;

namespace Code_Examples {
class PropertyGetter {
public static string listProperties(object someObject) {
StringBuilder sb = new StringBuilder();

List<pair> props = getProperties(someObject);

foreach (Pair prop in props) {
sb.AppendLine(prop.Name + ": " + prop.Value);
}
return sb.ToString();
}

public static List<pair> getProperties(object someObject) {
List<pair> dic = new List<pair>();

PropertyInfo[] props = someObject.GetType().GetProperties();
foreach (PropertyInfo prop in props) {
Pair t = new Pair {
Name = prop.Name,
Value = prop.GetValue(someObject, null)
};
dic.Add(t);
}
return dic;
}
}

public class Pair {
public string Name {
get;
set;
}
public object Value {
get;
set;
}
}
}

Monday, January 26, 2009

Logging snippets ready to go

My last post was some simple intro to how you can make your own snippets - here are some easy ones I made to make logging with log4net easier.

This first one is one I use simply to get a logger with the name of the current class. I put this in most every class. Nothing fancy here, just type log and press tab to get a logger named log.

<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>Logging
</Title>
<Author>Tomas Ekeli</Author>
<Description>Initializes a logger with the name of the current class</Description>
<HelpUrl />
<SnippetTypes />
<Keywords />
<Shortcut>log</Shortcut>
</Header>
<Snippet>
<References>
<Reference>
<Assembly>log4net.dll</Assembly>
<Url />
</Reference>
</References>
<Imports>
<Import>
<Namespace>log4net</Namespace>
</Import>
</Imports>
<Declarations />
<Code Language="CSharp" Kind="" Delimiter="$"><![CDATA[protected static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); ]]></Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>


Now you've got a logger up and running you'll be doing a lot of calls to log.debug("somestring") and even more with formatting on that string. So here's a snippet for that:


<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>logFormattedString</Title>
<Author>Tomas Ekeli</Author>
<Description>log formatted string</Description>
<HelpUrl></HelpUrl>
<SnippetTypes />
<Keywords />
<Shortcut>lsf</Shortcut>
</Header>
<Snippet>
<References>
<Reference>
<Assembly>log4net</Assembly>
<Url />
</Reference>
</References>
<Imports>
<Import>
<Namespace>log4net</Namespace>
</Import>
</Imports>
<Declarations>
<Literal Editable="true">
<ID>Level</ID>
<Type />
<ToolTip>Log level</ToolTip>
<Default>Debug</Default>
<Function />
</Literal>
<Literal Editable="true">
<ID>Message</ID>
<Type />
<ToolTip />
<Default>field value: {0}</Default>
<Function />
</Literal>
<div class="youtube-video"><object Editable="true">
<ID>Field</ID>
<Type>Object</Type>
<ToolTip>The field to log</ToolTip>
<Default></Default>
<Function />
</object></div>
</Declarations>
<Code Language="csharp" Kind="method body" Delimiter="$"><![CDATA[log.$Level$(string.Format("$Message$", $Field$));]]></Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>


Finally a very nice thing about logging is when you can push the context on a stack for inclusion. I use this all the time. This snippet can be used as a surrounding snippet as well (mark the text you want to surround in a context and right-click -> Surround-with


<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>logFormattedString</Title>
<Author>Tomas Ekeli</Author>
<Description>log formatted string</Description>
<HelpUrl></HelpUrl>
<SnippetTypes />
<Keywords />
<Shortcut>lsf</Shortcut>
</Header>
<Snippet>
<References>
<Reference>
<Assembly>log4net</Assembly>
<Url />
</Reference>
</References>
<Imports>
<Import>
<Namespace>log4net</Namespace>
</Import>
</Imports>
<Declarations>
<Literal Editable="true">
<ID>Level</ID>
<Type />
<ToolTip>Log level</ToolTip>
<Default>Debug</Default>
<Function />
</Literal>
<Literal Editable="true">
<ID>Message</ID>
<Type />
<ToolTip />
<Default>field value: {0}</Default>
<Function />
</Literal>
<div class="youtube-video"><object Editable="true">
<ID>Field</ID>
<Type>Object</Type>
<ToolTip>The field to log</ToolTip>
<Default></Default>
<Function />
</object></div>
</Declarations>
<Code Language="csharp" Kind="method body" Delimiter="$"><![CDATA[log.$Level$(string.Format("$Message$", $Field$));]]></Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>

Code snippets

I like anything which makes my day easier. Code snippets are one of these things. You can make your own code-snippets by editing xml directly, using the code snippet schema reference, or you could use a tool. Snippet Editor is just such a tool. With it making and editing snippets is dead simple!

One thing I've noticed with it, though, is that you cannot make a "SurroundsWith" snippet in this tool. To do this you have to edit the xml yourself. It's easy when you know how - just add the following to the header section of your snippet definition:


<SnippetTypes>
<SnippetType>Expansion</SnippetType>
<SnippetType>SurroundsWith</SnippetType>
</SnippetTypes>


And in your snippet section you add selected and end fields where you would insert the code you want to surround with the snippet (the following example would surround the selected code with curly braces).


<Code Language="csharp" Kind="method body" Delimiter="$">
<![CDATA[{ $selected$ $end$}]]>
</Code>

Tuesday, October 14, 2008

Developing ASP pages with Firefox

I prefer Firefox 3 to IE7 when developing (understatement of the week), particularly because it has Firebug and YSlow (an add-on for an add-on, would that be a quasi-add-on?). IE7 has the developer toolbar, but it's not as good (in my experience).
Naturally I have Firefox as my default browser, so when I launch ASP pages in the development server from Visual Studio they open in Firefox. And it is soooo slooooow. It's ridiculous, it's like being on my old 28.8 modem back in the mid-90s.
How can this be? Firefox isn't slower than IE7. That cannot be, no benchmarks point in that direction (OK, those are just javascript, but you get the gist of it).
It turns out the problem is with Firefox 3 and the development server (Cassini). I haven't dug deeply into it, just observed the problem, found the fix and applied it.
I've no time to check it right now, but disabling IPv6 seems a bit ham-handed. It should be possible to just include localhost in the network.dns.ipv4OnlyDomains preference. This is a string containing a comma-separated list of domains.

Technorati Tags: , , , , , , , ,

Tuesday, October 7, 2008

C# Compiler Could Not Be Created

I was having memory-problems on my dev machine (2 Gigs don't go far these days), and after a few resets I was getting an exception whenever I tried to open a solution containing a C# project in VS2005. It told me the C# compiler could not be loaded, and I should reinstall VS.
Eh? No way. That's an entire day, getting it back to where I want it.
So I open the Help -> About to see if I can get some info about what's wrong. There I'm hit by a Package Load Failure, coming from ReSharper (we loves it). This looks like something.
A quick google for this, and I find Aaron Stebner has a possible solution. The tool he references in that post didn't find any problems, but running through the steps to re-build the native libraries did.
So these are the steps in case that blog ever disappears:
  1. Open a cmd prompt
  2. Run del %windir%\Assembly\NativeImages_v2.0.XXXXX_32\Microsoft.VisualStu#
    (where XXXXX is the build number of the .NET Framework 2.0 that
    you have installed - you can figure that out by looking at the name of
    the folder at %windir%\Microsoft.NET\Framework\v2.0.XXXXX)
  3. Run %windir%\Microsoft.NET\Framework\v2.0.XXXXX\ngen.exe update /queue
That's done it. A restart of VS and we're up and running again. Now I just have to convince my boss I should get 2 more gigs of RAM.

Wednesday, October 1, 2008

Personal Information Numbers

A quick set of Regexes to check for Personal Information Numbers from the nordic countries.
I use these to check the format only, no fancy calculation of checksums etc.

  • Norwegian: DDMMYYXXXXX
    \b[0-4]\d[014]\d{3}\d{5} 

  • Swedish: YYMMDDCXXXX (C == '-' || '+')
    \b\d{2}[01]\d[0-3]\d[-\+]\d{4}

  • Danish: DDMMYY-XXXX
    \b[0-3]\d[01]\d{3}-\d{4}

  • Finnish: DDMMYYCZZZQ (C == '-'||'+'||'A' ; Q == [01234536789ABCDEFHJKLMNPRSTUVWXY])
    \b[0-3]\d[01]\d{3}[-\+A]\d{3}[0-9A-FHJ-NPR-Y]

  • Icelandic: DDMMYY-XXXC (C == 0 || 9)
    \b[0-3]\d[01]\d{3}-\d{3}[09]