5

I have a complex object that I'm trying to fake.

interface IContext
{
    User User { get; }
}

A.CallTo(
    () => _fakeContext.User.Subscription.Attributes)
    .Returns(new List<Attribute>());

But I get the next exception:

The current proxy generator can not intercept the specified method for the following reasons: - Non virtual methods can not be intercepted

All nested types are properties, and they are simple anemic types with get; set; property modifiers. And when I look into the debugger they all are fakes.

Is there any way to setup the last property of the chain and avoid setuping all previous ones?

Akim Khalilov
  • 1,019
  • 4
  • 16
  • 31
  • Are the property on `User` virtual? If so could you post the source code for `User`? – Xharze Jan 17 '13 at 15:42
  • No. Neither User nor Subscription are virtual. It's code from the compiled assembly. – Akim Khalilov Jan 17 '13 at 16:24
  • 2
    FakeItEasy cannot mock non virtual methods, so you have to resolve to build the object youself. Something like the answer below would do the trick. – Xharze Jan 17 '13 at 18:34

1 Answers1

3

If your objects are anemic enough, you might want to give AutoFixture a go:

var fake = A.Fake<>();
var fixture = new Fixture();
// If it's possible [1], AutoFixture will generate entire object graph
var user = fixture.CreateAnonymous<User>();
// Since data will be random [2], you can overwrite properties as you like
user.User.Subscription.Attributes = new List<Attributes>();
A.CallTo(() => fake.User).Returns(user);
  1. In order for it to work, your custom objects need to have public constructor and preferably avoid using interfaces (but that can be mitigated with auto-mocking extensions, like AutoFakeItEasy).
  2. The .Build method provides fluent API to customize objects autogeneration, so the randomness can be controlled
k.m
  • 30,794
  • 10
  • 62
  • 86