Feb 2, 2021
Welcome to Architect Tips presented by Clear Measure, a software architecture company. Empowering .NET development teams to be self-sufficient, able to move fast, deliver quality, and run their software systems with confidence. Make sure to subscribe on YouTube or your video podcast feed. If you have a question for the show, send them to architecttips@Clear-measure.com and the next tip could be yours.
Howdy! Welcome to Architect Tips. Today I want to talk about strategies for writing and maintaining automated tests for object-relational mapping whenever you have a hierarchy that you have mapped. And so on the screen, I have a sample just from a car auction, a car auction application, where we have an auction entry, but then we have three different types of entries. In an auction, things are typically called a lot. And if you're selling that, that sweet Chevrolet Corvette will be lot number such and such. And so you have competitive Lot, C of Consortium Lots, where multiple people can go in by organizations and you have an add-on only lot for donations, but they all derive from auction injury. So, in the code, you would see that a derived type lot would inherit from auction entering, okay? Well, what about your mapping? This is Entity framework and entity framework core or just entity framework and .NET 5 as well. And so, we're going to go to all auction injury map. We use this convention for every type of map, an aggregate root in domain design speak. We have an actual class so that the mappings don't get out of control and you want to be able to have a class per map. And if I go over to my data context, you can see that we have a method here that just kind of lists all of them and we can control the schema and in some cases, you want to put them in a different schema. That's just an aside but an auction entry, we've inherited, we've established it as table per hierarchy. So we've added a discriminator, okay, that's great. Just follow the documentation and in, in our code, we can find Consortium lot map and we can see that here, we have declared that our base type is auction injury. Although, even if you don't put that there, any framework, kind of figures it out. And this is our discriminator, it's only in the database, it's not in the object model and this derived type has an additional property in additional collection that are not on the base type. And so likewise we can go to another, the competitive lot. We can also go
to the, I add normally lot allow the donation that basically stays the same. There's no differences just yet. Although, this will grow. But over in our test, that's where it gets interesting. So I'm actually going to go to auction entry mapping tester and control F12. Notice that I have six different tests and over in Consortium, lot mapping tester only have two tests. However, because Consortium lot is at entry that means that all of the different queries and all of the different persistence and rehydration scenarios that work on auction entry should work for Consortium lot. So I have to duplicate those tests, the answer is no and this is how. So in our auctions remapping tester, we all we do is we take all of the tests that create an auction entry and instead we factor that out. We extract that as a method that returns auction entry and we market virtual. That gives us the ability to add some polymorphism given that our mapping is polymorphic when they are tests to be polymorphic as well. So we're going to do here, Control Alt B, we're going to look at derive types, and you can see that I have a mapping tester class for each of the drive types. And so if I look at Consortium lot, mapping tester, it, in fact, does inherit it overrides create auction entry and the usages of this are not found in this file. They're used in the base file. And so then we only have to actually have two more tests. Now, if I run it, my shortcut key. Alt Up and I run it, control TR. Let's let this run. And look, I have 11 tests for Consortium. Lot, mapping tester. Why? Well, it's because I have the two tests that are here, too. Plus, I have the six tests that are here. That's eight. But, let's go and look down. And a few of these tests have extra test cases. Okay, that brings us up to 11. So make your test fixtures polymorphic, and then all of your derived types, it'll be really easy to make sure that you are keeping to the rules of object-oriented programming and making sure that a drive type is an instance of the base type and we're not accidentally breaking some functionality that worked with the base type because I'll just jump up to bite you when you're using the application. And then there's some weird bug, it's because you're using a derived type that was returned back from query. So I hope this helps and make sure to subscribe to Architect Tips and whatever podcast directory you found us, have a good day.
Thanks for watching Architect Tips. If you would like, help improving your team speed quality or software stability. Send us a note to architecttips@Clear-measure.com. On behalf of everyone at Clear measure. Thanks for watching and may God bless you.