1

I'm writing some Persistence tests but am getting an error that NHibernate can't seem to work with FakeItEasy's fakes. Specifically the error is:

No persister for: Castle.Proxies.FacilityProxy

If I write the test like below it'll work fine and pass

    [Test]
    public void CanCorrectlyCreateFacilityTable()
    {
        new PersistenceSpecification<Facility>(session, new DataEqualityComparer())
            .CheckProperty(f => f.Id, 1)
            .CheckProperty(f => f.Name, _facility.Name)
            .CheckReference(f => f.Owner, new Client())
            .VerifyTheMappings();
    }

However, if I create a fake:

        IClient _client;
        _client = A.Fake<Client>();
        A.CallTo(() => _client.Name).Returns("Preston");

And pass that in to the test instead - it seems to fail with the error above:

    [Test]
    public void CanCorrectlyCreateFacilityTable()
    {
        new PersistenceSpecification<Facility>(session, new DataEqualityComparer())
            .CheckProperty(f => f.Id, 1)
            .CheckProperty(f => f.Name, _facility.Name)
            .CheckReference(f => f.Owner, _client)
            .VerifyTheMappings();
    }

Does anyone know if there's a workaround or possible error on my end?

I've done a bit of research here but can't seem to find this question already asked. Most seem concerned with FakeItEasy's configuration or NHibernate's configuration - which don't seem to be the problem: How do I test extension method of Nhibernate which does not return the value even after specifying return in fakeiteasy? Can I sensibly mock this NHibernate query?

Community
  • 1
  • 1
prestonsmith
  • 758
  • 1
  • 9
  • 29
  • 1
    I haven't used `PersistenceSpecification` tests in awhile, but if I remember correctly, isn't the whole point to make sure that the integration with the database is set up correctly? If so, why would you need to fake/mock the entity under test? – Andrew Whitaker Aug 10 '16 at 02:36
  • @AndrewWhitaker there are a few properties in the class Client that I'd prefer to remain protected as opposed to public. Mocking the class seemed the more elegant solution but, per Blair's answer below, I think I'll have to just use the class itself. Thanks for the reaching out though ! – prestonsmith Aug 10 '16 at 04:03

1 Answers1

1

I'm not an NHibernate user, so may not be much help. You may already know that the reason you see this behaviour is that FakeItEasy creates Fakes by (using Castle.Core's DynamicProxy class in the process of) creating an entirely new class that extends the faked class (or implements the faked interface).

You didn't provide the definition of the Client class, but I'm guessing that some member on it is of type Facility, so when the... property (I'm guessing) is accessed in order to persist the object, the returned value is of type FacilityProxy, and NHibernate doesn't know what to do with it.

It seems to me that the accepted answer in Can I sensibly mock this NHibernate query? has the right idea: test with an object of the actual type that you want to persist.

If that's unpalatable, I guess the only things that I can suggest are:

  1. configuring the Facility-typed property (again, I assume a property) to return an actual Facility (and probably doing this for an assortment of other members), or
  2. teaching NHibernate about FacilityProxy, although this might be hard. I don't know NHibernate, but since you don't have access to the class at compile time, it may be tricky
Community
  • 1
  • 1
Blair Conrad
  • 233,004
  • 25
  • 132
  • 111
  • Thanks @blairconrad - using the regular class isn't necessarily unpalatable, I just thought it'd be more elegant to use a mock in this case. I thought that perhaps Fake It Easy contained some other behavior I was unaware but I can change the tests to use "real" objects instead. Appreciate the help though! – prestonsmith Aug 10 '16 at 04:06
  • 1
    No problem. I hope it works out. While mocking objects can be useful when the "real" objects are difficult to use, in general I recommend using "real" objects whenever possible. You get a better indication of how your production system will actually behave. – Blair Conrad Aug 10 '16 at 09:48