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
Welcome to Typemock Community! Here you can ask and receive answers from other community members. If you liked or disliked an answer or thread: react with an up- or downvote.
0 votes
Hi,

I'm new to mocking, and I've encountered an issue. How to mock private accesses to a classes fields?

I want to mock a class that is persisted using an Object Relational mapper (NHibernate). This mapper accesses the private field _destinationGuid via reflection (I believe) but there doesn't seem to be an ExpectField method on the MockManager.MockObject class.

How do I catch the _destinationGuid access to return the appropriate value?

public class Destination
{
    private Guid _destinationGuid;

    public Guid DestinationGuid
    {
        get { return _destinationGuid; }
        set { _destinationGuid = value; }
    }

    public Destination() {}
}
asked by kerryr (1.8k points)

6 Answers

0 votes
Hi,
First welcome to the world of mocking.

Just to make things clear, mocking is used to isolate the code you want to test. This is done by setting up the behavior of classes that interact with the tested classes.

Basiclly it means that you mock Methods not fields.

In your case you can mock the DestinationGuid property as follows:
[Test]
public void MyTest()
{
    // Start 
    MockManager.Init();
    // mock next instance of Destination
    Mock mockControl = MockManager.Mock(typeof(Destination));

    // expect DestinationGuid to be called once and return dummyGuid 
    mockControl.ExpectGet("DestinationGuid",dummyGuid);

    // This is just a test to show how it works, 
    // you normally would put your real test here

    // this instance of Destination will be mocked
    Destination d = new Destination();
    // the Property will return our dummy result
    Assert.AreEqual(dummyGuid,d.DestinationGuid);

    // Check that all expected calls where made
    MockManager.Verify();
}


:arrow: Note: A better practice is to put MockManager.Init() in the SetUp method and MockManager.Verify() in the TearDown.
This will ensure that your types will always be mocked and that they will be verified even if the test threw an excpetion, thus not leaving any mocked classes alive between tests.
answered by scott (32k points)
0 votes
Thanks for the welcome.

The destination class that I'm mocking is referenced by another class called Orders. A similar concept might be an Order which has a related Customer.

I want to mock the Order class so I can test it's persistence without having to load/build the full Destination class (which is only there for it's guid).

Unfortunately my persistence library (NHibernate) uses reflection to access the DestinationGuid using the private field _destinationGuid. This means your code won't work as there is no access of the property, only the field level.

If I had a class with a public field (bad idea I know) how would I mock that?
answered by kerryr (1.8k points)
0 votes
I don't think that I understand the scenario.
If you want to put a value into the private field, then you can use the ObjectState class and change the value of the field.

But I guess that you want to mock the whole connection with the DataBase.
I don't really know NHibernate, but in that case shouldn't you just mock Configuration.BuildSessionFactory?
answered by scott (32k points)
0 votes
The (simplified) scenario is like this:

I have two classes Order and Customer.

What I want to unit test is the creation of an Order, and also that my NHibernate persistence settings work for that order - that it persists and retrieves correctly from the database with no corruption.

An Order has a reference to the Customer the Order belongs to. However, I don't want to retrieve an existing Customer from the database as this is outside the scope of the test; if customer retrieval is broken I don't want my Order creation test to fail. So I am looking to isolate my Order tests from my Customer class which has it's own unit tests.

So effectively, I want to write a unit test that exercises my Order code and Order persistence technique, but mocks up my Customer class.

Because of the way I map from the Customer class to the database using NHibernate, when I persist the Order it will result in NHibernate iterrogating a private field (Customer._customerGuid) to get the customer identifier the order relates to. It does this a few times, once to check whether the customer itself is newly created and needs persisting, and once for the foreign key in the database between Order and Customer.

So in my situation, it would be ideal if I could ask TestMock to also expect a couple of calls to the _customerGuid private field and verify that this has happened.

I understand this is probably not "pure" mocking, however I think it is a legitimate situation that should be catered for beyond the objectstate.

The objectstate answer will do though - thanks. I can run my orders tests now without retrieving a customer.
answered by kerryr (1.8k points)
0 votes
Hi,

I am glad that ObjectState solved your problem.

Of course you could also tell NHibernate to use private Properties getter and setters, instead of using the fields directly. Once you create access to the field via a property, you can easily mock and verify access to the fields.
answered by scott (32k points)
0 votes
I could do that but sadly my object model has checks and actions in property setters and getters in some classes, things that nHibernate shouldn't be subject to. To be consistent I'm pretty much stuck with private field access.

Go on, support field mocking and checks. I dare ya!
answered by kerryr (1.8k points)
...