0

I'm trying to debug the following line:

MOrigValue.AllInstances.TestString = () => "New value";

There's a red squiggly line under:

() => "New value";

Mouseover shows the following error:

Delegate 'Microsoft.Moles.Framework.MolesDelegates.Func<OrigValueP.OrigValue, string>' does not take 0 arguments 

Here is the complete class:

namespace OrigValueP
{
    public class OrigValue
    {
        public string TestString() { return "Original value"; }
    }
}

Here's the info from the object browser.

Click on the property MOrigValue.AllInstances.TestString:

public static Microsoft.Moles.Framework.MolesDelegates.Func<OrigValueP.OrigValue,string> TestString { set; }
Member of OrigValueP.Moles.MOrigValue.AllInstances

So, to a non-techie like me, that would explain the red squiggly line error above..

Click on the property MOrigValue..TestString:

public Microsoft.Moles.Framework.MolesDelegates.Func<string> TestString { set; }
Member of OrigValueP.Moles.MOrigValue

To me, this looks like the definition that I would have expected to see for MOrigValue.AllInstances.TestString. In other words a property that is actually a Moled "method" that has no parameters and returns a string.

As an experiment, based on the first object browser info above, I inserted the class as an input parameter, as follows:

MOrigValue.AllInstances.TestString = (OrigValue) => "New value";

This works :)

But my workaround looks like a "hack". I've seen every page on the internet (including StackOverflow) relating to moles and how to remove them painlessly. Many of them have lines with a lambda similar to the following:

MMyClass.AllInstances.DoSomething = () => "Hello world";
Assert.AreEqual("Hello world", new MyClass().DoSomething());

The fundamental issue is that Moles started from a method that takes no parameters and returns a string. The Moled equivalent takes its own class as a parameter and returns a string. Surely Moles knows that TestString() is a member of OrigValue.

Maybe my problem is a result of using VS Express, rather than the paid versions. I can live with that, but it would still be interesting to know why I need the hack. There might be cases where the hack produces incorrect test results without my knowledge.

BTW: I think this example proves the value of the object browser.

OldGrantonian
  • 597
  • 1
  • 8
  • 23

1 Answers1

0

Your expectation is wrong. The "hack" you describe is the official documented way to use the AllInstances nested type. Its delegates really do always take a parameter containing an instance of the type under test.

It is unlikely that you could have seen this form of usage of AllInstances

MMyClass.AllInstances.DoSomething = () => "Hello world";

which, if you have, could be a mistake made by the author of the code.

What you expect to be the definition of a delegate belonging to the AllInstances type is really a different kind of use of Moles: it's used to detour an instance method of a single instance.

The "Mole Basics" section of the document "Microsoft Moles Reference Manual" contains more information on the topic. Here is an excerpt from there.

Instance Methods (for One Instance)

... The properties to set up those moles are instance methods of the mole type itself. Each instantiated mole type is also associated with a raw instance of a moled method type.

For example, given a class MyClass with an instance method MyMethod:

public class MyClass {
    public int MyMethod() {
        ...
    }
}

We can set up two mole types of MyMethod such that the first one always returns 5 and the second always returns 10:

var myClass1 = new MMyClass() { MyMethod = () => 5 };
var myClass2 = new MMyClass() { MyMethod = () => 10 };
Gebb
  • 6,371
  • 3
  • 44
  • 56