Fixture Issue this.Container.Instances<T>() returns zero items

Jan 16, 2012 at 4:41 PM

Hi Richard,

I am trying to install fixtures using the InMemory Persistor for testing and am not having any success.

My setup is as follows:

  1. I have 2 factory/repository types: ClientFactory and UserFactory.  These implement a singleton pattern.
  2. ClientFactory is responsible for creating new Clients.
  3. UserFactory is responsible for creating new Users.
  4. Both ClientFactory and UserFactory singleton instances are added to SystemServices in NakedObjects for IOC DI.
  5. User instances require a Client instance, so UserFactory has a reference to ClientFactory so it can get at Client instances.  The reference is injected by the NakedObjects IOC Dependency Injection.
  6. Both ClientFactory and UserFactory derive from DomainObjectFactory.
  7. DomainObjectFactory derives from NakedObjects.Services.AbstractService.
  8. DomainObjectFactory has a virtual method called InstallDefaults() which allows each factory to be called to install any default data (fixtures) required.
  9. I also have a TestFixture type that derives from AbstractFixture. 
  10. TestFixture is added to Fixtures.
  11. TestFixture has a reference to both ClientFactory and UserFactory.  These references are injected by the IOC DI.
  12. TestFixture overrides the AbstractFixture.Install() method.  In the overridden method it calls the ClientFactory.InstallDefaults() and the UserFactory.InstallDefaults() methods.

My problem is as follows:

I can happily create and persist instances of User and Client as part of the fixture install process, without any errors, but when I try and get the instances from the container again, it always returns zero items.

public void InstallDefaults()
{
  // NakedObjectsContext.ObjectPersistor.StartTransaction(); // Seems to make no difference if I enable/disable transactions.
  try
  {
    var client = this.Container.NewTransientInstance<Client>();
    client.Name = "Test";
    this.Container.Persist<Client>(ref client);
    //  At this point 
    //  this.Container.Instances<Client>().Count() 
    //  returns zero items!
  }
  finally
  {
    // NakedObjectsContext.ObjectPersistor.EndTransaction();
  }

}

NOTE: When my test methods get instances from their container they are present!

Please can you let me know what I am doing wrong?

Coordinator
Jan 17, 2012 at 9:39 AM

I think this is expected behaviour. The fixture is called within a transaction by the framework. The actual persisting takes place on the end transaction once the fixture returns so the object store doesn't know about any new objects until the fixture returns.

Adding a transaction won't make any difference as it'll be nested and so won't end until the outer transaction ends.The usual pattern is just to keep references to the new objects as they are created by the fixture so there is no need to get them from the object store. 

 

 

 

 

Jan 17, 2012 at 10:28 AM

Hi All,

Thanks for the information, about the nested transactions.

I have now moved away from using AbstractFixture as the base class for my TestFixture in favour of AbstractService, and am now calling TestService.Install myself as part of the TestInitialize method rather than using fixtures and letting the framework call it automatically.  I have also added back the transactions and all is now behaving again :).

Once again, thanks for the amazing level of support you provide.