Seed test data in dotnet core?
One of the blockers which every developer will come across is when they want to test their methods with some data in the database or sample requests.
Thinking about it will sometimes make you go like,
But maybe I can be helpful. Let’s start.
Seed database with JSON
To me, creating some test data in the database in UnitTests always been tricky and was one of the reasons I always avoided UnitTests.
Remember there is no right or wrong in how you are doing your tests, Do it however you are more comfortable with it. But you may need to use some ideas 😉.
So what I do is that I create a
SeederBase.cs abstract class which looks like below. I will explain what it does.
The key point is the
InitData function. Let’s implement the abstract class and see how will it look like.
For example we want to seed some products. What the
SeederBase does is that it will take the name of the class which implements the abstract class and will search for a similar
json file with the same name of the class.
In the above class it will look for
Data/ProductsSeeder.json and will deserialize it to
List<Product> , then when you override the
Execute method you have access to the data you need to put into your database.
Well, I know that you can just write those data in C# and
Seed them there, but this is cleaner. Your code doesn’t need to have #Hard_coded data in it. Just gets the data and saves it however you want it to be saved.
Now let’s get to the part where you need to create a sample
DTO for your requests while UnitTesting.
Sample DTO from JSON
So since I like to categorize everything 😅 here I like that every test class has a directory in let’s say
/Data directory. In each directory there is a collection of
json files which contains different
DTO samples for different cases.
So if you have checked the following post, you should already have a TestBase abstract class.
How to have more fun with UnitTests in dotnet core
Let’s get started with UnitTesting and see how easy it is to do it. There is no wrong way or right way, just do it and…
In that abstract class I always have a
GetDto<TData>(filename) method. The implementation is like this:
If you notice, it kinda have the sample logic as the
SeederBase . It reads the name of the class which is implementing
TestBase and will look for a directory with the same name in
/Data . For example let’s say you have a test class like
CreateProductCommandTests so then you should have this directory available
/Data/CreateProductCommandTests/ and if you want a dto, from one of your
TestCases — Facts you just simply get it like,
var dto = GetDto<CreateProductCommand>("CreateProductDto");
The above call, will get the json from
/Data/CreateProductCommandTests/CreateProductDto.json and will deserialize it into
CreateProductCommand which if you are using
MediatR will be the data that your
CreateProductCommandHandler will use to run.
Well this one was a short one but efficient I guess.
Incase you want to see the usage in action please take a look here :)
Let me know what you think or if you have other methods please share it with us.
Have fun coding ❤️