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
I'm having trouble mocking a class in an interface, which I'm also mocking as an object. See the code example below:

Interface
public interface ITrackingView
{
SessionTracking SessionTracking { get;}
...
}

Class
public class TrackingPresenter
{
private ITrackingView _tracking;

void AddTracking(object sender, EventArgs e)
{
TrackingServiceClient client = new TrackingServiceClient("...");
Session session = new Session();

session.Agent = _tracking.SessionTracking.UserAgent;
...

client.AddSession(session);
}
}

Unit Test
...
MockObject mockInterface = MockManager.MockObject(typeof(ITrackingView));
mockInterface.ExpectGet("SessionTracking.UserAgent", session.Agent); //THIS FAILS
...

How can I mock this SessionTracking object? I hope that this explains what I'm trying to do.

Thanks,
Eric
asked by eschatzy (3.8k points)

4 Answers

0 votes
You are basicly wanting chained calls.
Using Natural Mocks this is easy. Just call it.
ITrackingView tracker = 
 RecorderManager.CreateMockedObject(typeof(ITrackingView));

using (RecordExpectations recorder = RecorderManager.StartRecording())
{
    tracker.SessionTracking.UserAgent;
    recorder.Return(fakeAgent);
}


If you don't have a license, you can create all the objects manually.
// create Session type and make sure that the fake agent is returned
MockObject mockSession = MockManager.MockObject(typeof(SessionTracking)); 
mockSession.ExpectGet("UserAgent",fakeAgent);

// make sure that our mocked session will be returned when SessionTracking is called
MockObject mockInterface = MockManager.MockObject(typeof(ITrackingView)); 
mockInterface.ExpectGet("SessionTracking",mockSession.Object);
answered by scott (32k points)
0 votes
Thanks for you help. Chaining was what I was looking at, but I only have the Professional version. This has solved my problem up to the next point.

Unit Test

...
MockObject mockSessionTracking = MockManager.MockObject(typeof(SessionTracking));
mockSessionTracking.ExpectGet("UserAgent", session.Agent);

MockObject mockInterface = MockManager.MockObject(typeof(ITrackingView));
mockInterface.ExpectGetAlways("SessionTracking", mockSessionTracking.Object);
...

At this point the mockSessionTrack object has a value for the UserAgent property.

Code
void AddTracking(object sender, EventArgs e)
{
TrackingServiceClient client = new TrackingServiceClient("...");
Session session = new Session();

session.Agent = _tracking.SessionTracking.UserAgent; // FAILS
...
}

But on the _tracking.SessionTracking.UserAgent property it is throws a System.NullReferenceException. For some reason the value is not being translated from the mockSessionTracking UserAgent property to the _tracking.SessionTracking.UserAgent property.

Thanks,
Eric
answered by eschatzy (3.8k points)
0 votes
This really depends on other parts of the code.
Perhaps _tracking is not set to your mock object, check how to pass the mock object into the code.
Perhaps the session.Agent you are returning is null.

:arrow: Take a look at the tracer to see which instance and method is not being called.
answered by scott (32k points)
0 votes
I figured out what the problem was.

Unit Test
...
MockObject mockSessionTracking = MockManager.MockObject(typeof(SessionTracking));
mockSessionTracking.ExpectGet("UserAgent", session.Agent);

MockObject mockInterface = MockManager.MockObject(typeof(ITrackingView));
mockInterface.ExpectGetAlways("SessionTracking", mockSessionTracking.Object);
...


The UserAgent property in the mockSessionTracking object would return the value correctly the first time, because it was an ExpectedGet call. For some reason I believe that the ExpectGet fired when I created the mockInterface and set the mockSessionTracking.Object to the SessionTracking Get property. At this point the UserAgent property would throw a System.NullReferenceException.

To fix this I did the following. Set the UserAgent property to ExpectGetAlways. Then it works all the way through the unit test where the the actual call is made to the UserAgent property.

Unit Test
...
MockObject mockSessionTracking = MockManager.MockObject(typeof(SessionTracking));
mockSessionTracking.ExpectGetAlways("UserAgent", session.Agent);

MockObject mockInterface = MockManager.MockObject(typeof(ITrackingView));
mockInterface.ExpectGetAlways("SessionTracking", mockSessionTracking.Object);
...

Thanks for you help,
Eric
answered by eschatzy (3.8k points)
...