Learn about unit testing, create a test project, and install xUnit in preparation for the next video.
- [Instructor] As you saw in the example files there's two projects. One that holds all of our, any new framework code, if you data access library. And there's another project that was set up called gal.tests and in that project we're going to put our unit tests. So a little bit about unit testing and how we're doing it. I'm using xUnit for this course. xUnit is free, it's open-source. It supports anything that you can do in Visual Studio, so not only the full .NET Framework but also .NET Core.
And then there is a Visual Studio runner that you can download as well from NuGet. And if you want more information you can get it at the link that is shown. If you used a different unit testing frameworks such as NUnit, or MbUnit, or even MSTest, there's a couple differences that I want to call out here before we dive into the code. The first is that tests are decorated with the [Fact] Attribute. Instead of calling it a test, we call it a fact.
If you want a data-driven tests, you decorate it with the [Theory] Attribute, and then you'll add in additional rows of data by using the inline data attribute. And lastly, parallelism is on by default, and this affects us because when you're testing against the data base, parallelism can cause some problems with the testing. And then finally just to be clear, I'm calling them unit tests, I guess academically, they're really integration tests.
Right, 'cause I'm testing all the way to the data base? But for sake of simplicity I'm going to continue using the phrase unit tests throughout this course. Now it's time to look at the code. So the first class I want to talk about is the Base Test class. And this just holds some of the plumbing that we will use in every test. So we've got the IntroToEfContext property, and we instantiated it in the constructor, and then we also add in IDisposable.
Now with xUnit, if you make your tests implement IDisposable, then the constructor is run before every test and the dispose method is run after every test. So you could think of it as set up and clean up but it's just constructor indisposed. So here on line 12 we are instantiating a new context. And on lines, let me scroll down here a little bit, 15 through 21 we are cleaning up.
So anything we might have done to the data base, adding new records for example, we are cleaning them up. So we're deleting everything from categories and products, which are the only two tables that we used in this class, and then we're setting the identity. This way I can guarantee that the identity doesn't keep changing and my tests become less brittle. If we look at the ReadDataTests, we'll see that we've got a constructor here and starts on line 16.
What this is doing for us it's setting up, a range is used typically with TDD and BDD, but it's setting up all the records that I need to then test. So I've got a helper class here AddCategory. If we want to look at that, it's very very simplistic, it just executes a sequel command. And what I'm showing here is the data base property of a db context that allows you to execute sequel commands and do other straight up functions. So even though it is an ED framework, we don't always have to go through the object model, but all the capabilities of that are beyond the scope of this intro.
The next thing I want to call out is on line 12 we have a collection attribute. And the way parallelism works with xUnit is any tests that are in the same collection will not be run in parallel. By default the class is a collection but you can expand that with a collection attribute as I have here and put all of the tests into one collection so they will all run serially.
Collection takes the string, I prefer to put a constant in there so I don't have to worry about fat fingering it. Doesn't matter what the string is, it just has to be the same if you want all the classes to be in the same collection. If we look down here, we have some tests that are not yet implemented, decorated with a fact. I could also change this to a theory and then I would pass in data like this.
I can pass in any data type and then I have to have matching parameters on my test method. So this would be string, some number, et cetera. So we're going to clean this back up to way it was before. And we're going to go ahead and close file, not saving any of those changes. So it is back to where you downloaded it. So in this module we just very briefly covered xUnit and the classes that I've created for you as a starting point.
Next module, we're going to be using these extensively to test any of the framework and use it to drive our crud operations.
- Configuring entities
- Examining generated classes
- Installing EF tools
- Unit testing
- Creating, reading, updating, and deleting data