CapableObjects › Forums › SupportForum › ExternalId with PersistenceMapperMemory
Tagged: externalid, PersistenceMapperMemory, tdd, test driven, unit test
This topic contains 5 replies, has 2 voices, and was last updated by krilbe 5 years, 2 months ago.
-
AuthorPosts
-
For some unit tests, I create my EcoSpace with PM replaced with PersistenceMapperMemory. Works fine, but now I need to test code that uses ExternalId. But when I call the extension method
IEcoObject.ExternalId()
, I get an exception:System.InvalidOperationException: ‘MappingProvider has not been initialized’
What could be causing this?
The code that creates the EcoSpace looks like this:
SyncHandler sh = new SyncHandler(); PersistenceMapperMemory pm = new PersistenceMapperMemory(); pm.SyncHandler = sh; return new MyEcoSpace(pm);
And that constructor looks like this:
public DiamondsEcoSpace(PersistenceMapper pm) : base() { InitializeComponent(); persistenceMapperSharer = null; PersistenceMapper = pm; OtherInitializations(); }
I tested with my regular PM and the code works in that case.
Maybe PersistenceMapperMemory just doesn’t support external id:s?
In that case, how would I implement such a service to be able to test my code?
I would prefer a mock (NSubstitute), but how do I get it “installed” so it’s used in my test EcoSpace?
When I use an EcoSpace for testing, I don’t use the normal EcoSpace. I use a TestEcoSpace that is configured using a PersistenceMapperMemory. And: PersistenceMapperMemory supports external IDs perfectly. You only have to update the database as you would do for an ordinary EcoSpace after creating data in the EcoSpace.
I’ve made very good experiences using SpecFlow (behavior driven development) by using Gherkin and entering test data in a table form.
Thanks Peter. Good to know. So, then I wonder what might be wrong in my case… Why do I get that exception?
Can you post your setup code for that memory mapped EcoSpace of yours?
Trying to debug the issue, I found that during EcoSpace construction, this method gets called:
protected override Eco.Services.Impl.ExternalIdServiceBase CreateExternalIdService(Eco.UmlRt.IEcoTypeSystem typeSystem) { return new Eco.Services.Impl.ExternalIdServiceImpl_DbType(typeSystem, (DiamondsPMP.Instance.PersistenceMapper as Eco.Persistence.AbstractPersistenceMapperDb).EffectiveRunTimeMappingProvider); }
I think I added that override when I wanted to use the DB type discriminator rather than the internal type index for my external id:s.
Since this gets called in the constructor’s
base()
call, I have no way to pass any parameters or settings to it. Instead, I would need to change the ExternalIdService afterwards, in my custom constructor code. But I fail to find info about how to hook it up. Is it sufficient to simply register a new instance ofExternalIdServiceBase
to the service provider?Another option would be to have a static flag in
MyEcoSpace
class, that would alter what the method above returns.Suggestions?
So I ended up creating a static method
MyEcoSpace.CreateMemoryMapped
which sets a private static flag before instantiating the EcoSpace. In theCreateExternalIdService
override I check this static flag, and return a regularExternalIdServiceImpl
if set, otherwise theExternalIdServiceImpl_DbType
that I want for regular use. Seems to work.If anyone can come up with a simpler or less ugly solution, feel free to comment. 🙂
-
This reply was modified 5 years, 2 months ago by
krilbe.
-
This reply was modified 5 years, 2 months ago by
-
AuthorPosts
You must be logged in to reply to this topic.