views:

520

answers:

3

Hello,

How can I do this in Moq?

Foo bar = new Foo();
Fake(bar.PrivateGetter).Return('whatever value')

It seems I can only find how to mock an object that was created via the framework. I want to mock just a single method/property on a concrete object I've created...

In TypeMock, I would just do Isolate.WhenCalled(bar.PrivateGetter).Returns('whatever value')..

Any ideas?

+2  A: 

Only TypeMock Isolator (and perhaps Moles) can perform these stunts. Normal dynamic mock libraries can only mock virtual and abstract members.

Mark Seemann
Good to Know - wish there was more info on Moles out there - haven't heard anything on it at all yet as far as people using it here on SO
dferraro
FWIW, here's the official site: http://research.microsoft.com/en-us/projects/moles/
Mark Seemann
+4  A: 

You should use Moq to create your Mock object and set CallBase property to true to use the object behavior.

From the Moq documentation: CallBase is defined as “Invoke base class implementation if no expectation overrides the member. This is called “Partial Mock”. It allows to mock certain part of a class without having to mock everything.

Sample code:

    [Test]
    public void FailintgTest()
    {
        var mock = new Moq.Mock<MyClass>();
        mock.Setup(m => m.Number).Returns(4);
        var testObject = mock.Object;
        Assert.That(testObject.Number, Is.EqualTo(4));
        Assert.That(testObject.Name, Is.EqualTo("MyClass"));
    }

    [Test]
    public void OKTest()
    {
        var mock = new Moq.Mock<MyClass>();
        mock.Setup(m => m.Number).Returns(4);
        mock.CallBase = true;
        var testObject = mock.Object;
        Assert.That(testObject.Number, Is.EqualTo(4));
        Assert.That(testObject.Name, Is.EqualTo("MyClass"));
    }

    public class MyClass
    {
        public virtual string Name { get { return "MyClass"; } }

        public virtual int Number { get { return 2; } }
    }
Ariel Popovsky
Thanks, I will try this. Makes TypeMock look more and more tempting though. Ugh!
dferraro
This didn't work - it gave error message on the mock.Setup() line (in second example) "Test method CRMFundOfFundPluginsUnitTest.FoFPluginBaseTest.SetMissingTargetValuesTest1 threw exception: System.ArgumentException: Invalid setup on a non-overridable member:m => m.InputTargetDE.".Any idea why?
dferraro
Make sure the methods you are mocking are virtual so Moq will be able to override them.
Ariel Popovsky
+1  A: 

Moles can also replace private methods as long as the types on the signature are visible. So in this case, it would look like this:

MFoo bar = new MFoo { // instantiate the mole of 'Foo'
    PrivateGetterGet = () => "whatever value" // replace PrivateGetter {get;}
};
Foo realBar = bar; // retrive the runtime instance
...

If you are looking for more information on Moles, start with the tutorials at http://research.microsoft.com/en-us/projects/pex/documentation.aspx.

Peli