chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
0 votes
Hi,

I just wanted to clarify some unexpected behaviour I encountered when mocking a public property. Consider the following class;

public class SimpleClass
{
    private string _name;

    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }
}


The following unit test passes yet checking the code coverage, neither the getter or setter of the property are covered;

[TestMethod]
public void TestNameProperty()
{
    string mockName = "TESTNAME";
    SimpleClass simple = 
        Isolate.Fake.Instance<SimpleClass>(Members.ReturnRecursiveFakes);
    Isolate.WhenCalled(() => simple.Name).CallOriginal();

    simple.Name = mockName;

    Assert.AreEqual(mockName, simple.Name);
}


I discovered that this is down to omitting the following line of code that overrides the behaviour of the fake on the setter as well as the getter;

Isolate.WhenCalled(() => simple.Name = null).CallOriginal();


This led me to question why the original test passes at all as I have, in effect, mocked the getter and not the setter so the getter should return null and the setter would just be ignored.

By contrast, if I only mock the setter and not the getter, then the test fails as expected as the setter works by calling the original implementation and the getter returns a fake.

Is this expected behaviour?

Thanks
Steve.
asked by stephencampling (3k points)

4 Answers

0 votes
Hi Steve,

Yes this is the expected behavior :)
What you see is what we call [url=http://docs.typemock.com/Isolator/##typemock.chm/Documentation/PropertyBehaviorAAA.html]true properties[/url]. That means that for properties of faked class you can skip the "Isolate.WhenCalled ..." dance.
The line:
simple.Name = mockName;
is actually like doing:
Isolate.WhenCalled(() => simple.Name).WillReturn(mockName);
so later in the code
Assert.AreEqual("TESTNAME", simple.Name) will pass.

Hope it clears things up.
answered by ohad (35.4k points)
0 votes
I'm a touch confused still.

In my example, I've faked an instance of a class using the Recursive Fakes option. I''ve then requested that the getter of the property uses the original implementation, yet in my assertion when the getter is called, it returns the mocked value rather than calling the original implementation as requested and failing?

Is the fact that I have Recursive Fakes and haven't set up an override for the setter causing the true properties feature to be invoked and discarding my behaviour of call original for the getter?

Thanks
Steve.
answered by stephencampling (3k points)
0 votes
Hi Steve,

Sorry I think misunderstood you at the first post.
When you used:
Isolate.WhenCalled(() => simple.Name).CallOriginal();
simple.Name = mockName;

Isolator created an expectation for the getter in the second line. This expectation overrides the the CallOriginal behavior.
I think this is a bug. There are two options for fixing the bug:
1. The CallOriginal behavior will apply to both getter and setter.
2. The CallOriginal behavior will apply only to the getter and setter will return the default behavior of recursive fakes.

What would you choose?
Personally I would choose option 1 since most users tends to see a property as one method, but I may be wrong here :)
answered by ohad (35.4k points)
0 votes
Hi I'd personally prefer the second option as I feel its more explicit.

Thanks for getting back to me.

Kind regards
Steve.
answered by stephencampling (3k points)
...