1

We're using NUnit (2.5.9) and NMock2 for unit testing and mocking. Both, however, have a matcher syntax that closely corresponds. When I do

using NUnit.Framework;
using NMock2;

And later on the following NMock2 code:

Expect.Once.On(database).Method("Create").
  With(Has.Property("id", Is.EqualTo("012345678901")));

But also an NUnit assertion:

Assert.That(someValue, Is.EqualTo(54321));

Then VS (2008) will complain that 'Is' is an ambiguous reference between 'NUnit.Framework.Is' and 'NMock2.Is' (and same for 'Has').

Is there any way around this? It seems that both matchers have similar functionality anyway. Prefixing each matcher class with the full namespace of course works, but it makes tests significantly less readable.

Google searches for this issue have found no match at all, so my underbelly feeling is that i'm doing something very stupid.

skrebbel
  • 9,841
  • 6
  • 35
  • 34

3 Answers3

3

You can avoid using the Nunit fluent syntax.

Assert.AreEqual(54321, someValue);

And then use aliases in conjunction.

using NMock2;
using Is = NMock2.Is;
using Has = NMock2.Has;

This will force your application to take the NMock versions of these classes. If you wanted to get to the NUnit ones, you would have to give a full name including namespace.

Another option to preserve both would be to use the following namespace declarations and aliases.

using NUnit.Framework;
using Is = NUnit.Framework.Is;
using NMock2;
using WithValue = NMock2.Is;
using Has = NMock2.Has;

Now you can use both fluent interfaces, but the code reads

Expect.Once.On(database).Method("Create").
  With(Has.Property("id", WithValue.EqualTo("012345678901")));

Assert.That(someValue, Is.EqualTo(54321));
NerdFury
  • 18,876
  • 5
  • 38
  • 41
  • Ah, nice point. However, I'll still get the ambiguous reference on the NMock2 matcher class 'Is', because there's still also an 'Is' in NUnit.Framework.. Any trick for that? – skrebbel Mar 21 '11 at 11:15
  • @skrebbel I had it in my head that the fluent interface was in a different namespace then the basic assertions. But I just checked in my project, and I was wrong. – NerdFury Mar 21 '11 at 11:31
  • @skrebbel I came up with a solution that works with aliases that I think is pretty clean. One way if you want to not use the NUnit fluent interface, another if you want to preserve both fluent interfaces. I don't have much experience with NMock2, and the WithValue alias might not always make sense in the fluent interface, but it works in your example. – NerdFury Mar 21 '11 at 11:47
  • *wow*. ok that's pretty hardcore :-) I'm torn that even though NMock is supposed to have been designed for NUnit they didn't resolve this (I really hoped that I had just forgotten to flip some switch), but I like your workaround :-) – skrebbel Mar 21 '11 at 12:37
3

Interestingly enough NUnit also exposes a little class called Iz that you can use to avoid this naming collision with NMock2. So for example instead of:

Assert.That(someValue, Is.EqualTo(54321))

you can write

Assert.That(someValue, Iz.EqualTo(54321))

May not be the cleanest, but it doez work ;)

Sebastian K
  • 6,235
  • 1
  • 43
  • 67
1

Use Namespace aliases if you need to use constraints. Eg.

    using N = NUnit.Framework;
    using M = NMock2;

Then

Assert.That(someValue, Is.EqualTo(54321))
would become
Assert.That(someValue, N.Is.EqualTo(54321))
grizzly
  • 1,146
  • 12
  • 26