Integration testing | ASP.NET Core 5 REST API Tutorial 15

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

That's very helpful! Thanks!

👍︎︎ 1 👤︎︎ u/WhoAlreadyKnewThat 📅︎︎ Jul 09 2019 🗫︎ replies
Captions
hello everybody I'm Nicolas I'm going to show you how I can start writing integration tests in the speed of color now there's a reason why I'm not going into unit tests now when I'm going straight into integration test is because it's probably what you're not as familiar with since this technique was only recently added and I do say recently it's more like a year since to point something in asp.net core so we're gonna go through that first and later in the future we are going to talk about your interests and if you want to see more like this please subscribe a little like or just comment down below what you want me to show you in a future video so let me just go straight to the point what is integration tests or integration tests is a way to ensure that your application can actually function properly while communicating with other components in the system that might be the data base the file system networks or other pipelines that you might have set up in your application such as bid where so the way we're gonna go about it is we actually are going to be hitting a running application our API will be running as normal the only difference is it's going to be in memory as part of the testing and we're gonna use a unit testing framework 2 integration tests or API so I'm going to show you how to do this very cool a nice way to get started with integration tests so first and foremost you want to go and create a new project I'm using writer here so as you can see so I have this creation a project window you might have a different one depending on your ID so yeah just go ahead and say to it work dot integration tests and that's just a naming convention that I use you can use your own of course so we create that and you can see that there's a just a blank test that has nothing if I open my testing window which should be here you can see that I have this view and I can just select this and run my tests and I expect this to pass and that's just a normal unit test using X unit what we are gonna do is we are gonna spin up the application and target this application so run cold games are running API so the way we're going to do that is using something called the web application Factory and that's something added in to point something in the core and to actually use that we do need several packages first and foremost we will need a package called Microsoft HP net core MVC testing so let me just go ahead and add that and we will need the HP Dada core dot app package that has a lot of packages in it so it's like a collection so we need both of this so as we wait for these packages to install I'm gonna go ahead and show you how this thing works now we're gonna delete this whole class but I just want to show you how it worked before I go and implement this thing the actual way so we're gonna have an HTTP client let me just name its client but this is a special exited client will be coming from this new class I talked about which is the web application factory so if I do up the factory equals web application factory and this accepts a startup class so I'm gonna use my application startup and obviously cannot find it because it's not referenced I'm gonna go ahead and reference my Twitter book application so start up and I have my database running as well so if I do create client just like that I'm creating an app Factory and if I do app factory dot create so sorry I already created the client so I don't want to do that and if I do after to create client here what I get back is an HTTP client who's very interesting one it will have some base address but that won't be used this is an HTTP client a special one that knows how to target an in-memory version of this project which is whichever project the startup belongs to so let me just go ahead and show you in practice what will do let me do a get async on an API roots dos let's say post-ops yet and this should accept the post ID so let me just replace that and say in place post ID with whatever one and let's get a response back so I'm gonna change this donation task let's take a break point here and just run it and see what I get so this goes into our unit test constructor and that will be very interesting because I have the app factory and the app factory has many things it has a server which is currently null it's a test server object that's an in-memory test server then I have our configuration some factories and then I have some options here as as you can see the base address is just this but it won't really be used the moment I trigger this create client method you can see even in this app factory here that the server is no longer than all we have an in-memory server with this same base address that can only be accessed by this very HTTP client and we are going to use this client as you can see here to just call this server as if it was a running application and if I do that you can see that I get an unauthorized and that's because well my barrier token is not actually set and that's what you'd expect from an API running without birds ok this behaves exactly the same way keep in mind this is actually using this very same database here the one we set up some episodes ago and nothing is mock this is the real deal it's just that the server is running in memory this is a very interesting concept I'm gonna do is I'm gonna delete this I'm gonna show you how we can properly implement this and start integration test for obligation so first and foremost I'm gonna do create an integration test class and the reason why I do this is because all of my other test classes will actually extend this base class and in the constructor I'm gonna set up my test client the same way I did in this video this will be protected read-only HTTP client and I'm going to name this a test client and I'm gonna initialize it so again up a factory equals new web application factory and then the start of template case we want to run and the test file equals AB factory dot create client now we're going depth on this app factory but you're gonna see whatever you need to know about you can do more reading on yourselves afterwards to see there are many cool things you can extend here if you really wish do but I'm only showing everything here so please if you're interested just google it afterwards so a nice convention I like to use for my tests is use the controller name post controller and then tests I'm gonna create my test class to be posts controller tests because I'm going to be testing this controller and this test class will be extending the integration test class in X unit in order to test when in the fact attribute so I'm gonna make a public async task which a convention I like to use is the controller method name so in this case will be get all and an underscore and then I'm explaining what I'm doing so get all with empty or with without any costs returns and the response something like that you don't have to follow this convention is just one of the many many ways you do it but I do like to follow this one at least for the tutorial it's clean and something else I wanna follow is the Triple A or arrange act assert just to separate what I'm doing in this test method so you can actually see clear what I'm actually doing so to arrange first and foremost we need to do some setup currently the only thing we need to do is to just authenticate ourselves because if I try to access this currently I'm gonna get as you saw before a 403 unauthorized so in my base class I just changed protected as well it might miss class I'm gonna make a method and this method will be called authenticate so I'm gonna make a protected method named it's gonna be an async task and I'm gonna name this method of fan decayed async and let's just leave it here as it is for now and what this will do is it will set the default header for authorization on our client and it will actually be getting a nature at JWT for our client so I'm gonna do bearer and then here I'm gonna say get J WTI sink and I'm gonna create this method it's not being an async task which returned the string I have no weight here of course and this method I don't know why this is not accepted this should be involved with how of course this is the wrong overload it's a new value okay so this is final and now this should somehow return a valid JWT for my test the way I will go about this now is just register a user since xunit runs the test once per execution so this class will be instantiated once per tests this will be fine our user will be registered every single time we run the test we could do setup and teardown but we're using any different work because we're using an T framework we can cheat well we don't really cheat but what we really do is we just change our signal server database with an in-memory one and this specific class has a very interesting way of going about it what I'm going to do is I'm going to say after application factory with what post builder and I'm gonna say builder and in this lambda expression I'm gonna say beta dot configure services I have my services here and these services are the services of this necessary as we gonna spin up at this point our startups execution has been finished everything has been configured up on this at this point and I can actually configure more stuff here what I'm gonna do instead is I'm gonna say services dot remove all and I'm gonna remove all types of our data context because this is a data context that's using real sequence every structure I don't want to do that what I will do though if writer lets me is the services dot and DB context and then add the data context and I have some options here and these options will say options code use in memory database and I'm gonna give this a test DB name or something and now I have this setup and this application now no longer uses this real database is using an in-memory one meaning I can just register every time without any clear down and we just work and this is a realistic representation of how your application would work now if you need acceptance testing you really want to test against a reality structure you want to spin up docker instances maybe or just do teardown cleanups afterwards but that's up to you so in this method I'm gonna do bar responds equals and I'm gonna use this very test and to do a post ask Jason I sang API roots I'm gonna say identity dot register and I'm gonna post no new user registration request and it's a request to register a user for those tests to get a token back essentially so test app if the creation.com maybe the toilet and then password equals some pass one two three four exclamation mark just an example and at this point we have our registration response object and I'm gonna say await response dot content after a white case of compose the content dot read ours async and we're gonna read it as of success response what I'm going to read back is the registration response dot talking and I have my JWT here so at this point in order to indicate my test all I need to do is here say a weight off at the gala I think and that's it my HDB client will be automatically authenticated so see what the test looks like we will do an awake here and then test client and I'm gonna do a get a sync with my dedicated client against the API root dot post dot get old and what I want is to validate that this response is a two hundred and my content is an empty list because there are no posts in the database to return what I really like to do with my tests is use a package called fluent assertions this package exactly as the name implies allows me to fluently assert my unit tests you know with a package here I can do response dot status code be and then my status code so ATP status code okay because that's what I want it to be and then response dot content read arts and that should be a list of posts should be empty assuming I did everything right if I add this fat attribute here my test will appear and I'll be able to run it and it should pass let me expand this as you can see my test is passing it's doing exactly what I said it would do if I change this and I say not found or not acceptable or anything else my test should fail because the request or the response should not be what I wanted to be exactly see it's not acceptable but found okay so this is an integration test that is hitting an in-memory version of my application which is using an in-memory database not a mock just an in-memory version to run integration tests this is a very awesome feature and I really really love writing test this way let's see a few more just so you get a better idea of what we're doing so another thing I'd like to do is show you how you can actually ensure that the post is created and can be retrieved so the test would be something like async task yet is it called get by ID what do we name it it should be get okay so yet will turns post when post exists in the database the system all just exists naming can be whatever you to be so first and foremost we want to authenticate so authenticating and now we need another method in our integration tests class and this method will be called protected async tasks can't in a post response shall be called create post pacing and we accept a create post request and we're going to use that to create one hitting the endpoint so test client dot post as is an icing again API roads posts create nothing else needed here and then the request itself and I'm gonna get the response back to please once and I'm going to return the response dot content dot three does pacing I'm gonna read it as a post response which is what it is really and if I actually await this it should be happy so that is fine now I can go back to my test and say a white create post icing and I'm gonna create a new post with name equals test post keep in mind that it's of these tests are running in isolation so anything I created here doesn't affect anything I do here if I wanted to test it this way I would use an eyeglass fixture in this scenario but we don't need to do that it's equally as far as to spin up one server at a time if you want to test more you can but I've noticed some disposal issues of my HTTP client if I use a class picture here so I won't show that I'm gonna do is I'm gonna do var response equals a weight test client dot I'm gonna do a get a sink and what I'm gonna get I'm gonna get a post the post I just created so we place here and I'm gonna replace the talk in the post ID taught you to use the create post one if I do sign name ID the string cause it's a good so I have the response here and this should actually retrieve exactly what I wanted so I'm gonna say status code should be HTTP status code okay because we retrieve something we created and then a wait response dot content don't we as they think I'm gonna read it as a post which is what it is and let me just extract it here as we trying to post so I can do multiple sessions on it so return post dot ID should be and it should be the create post dot ID and the return post dot name should be and it should be the test post you have here so [Applause] if I build this and run it both my tests should pass again unless I screwed up as you can see both of them pass both of them work you can take this even further you can test that your creation is working you test in a very similar way where you just have this in your act and then your assert is the retrieval itself to see that it's actually created but this so many ways you send so many things you can do this is just the basics as I said before if you want to test against against the real database you just comment this out and this will run it against the real database but you will need teardown or cleanup methods after the test is run that's all I want to show for this first video if you want me to go in-depth on this comment down below and I'll make more videos on how you can run integration tests Youth tests are on the way as well if you want some Pacific don't forget to comment about it down below leave a like if you like this video subscribe for more content like this and i'll see you in the next video keep coding you
Info
Channel: Nick Chapsas
Views: 66,070
Rating: undefined out of 5
Keywords: Elfocrash, elfo, coding, asp.net, .netcore, dot net, core, C#, how to code, tutorial, asp.net core, javascript, js, 2.2, csharp, rest, rest api, development, lesson, software engineering, dev, microsoft, microsoft mvp, .net core, nick chapsas, chapsas, integration testing, integration tests in .net core, webapplicationfactory, xunit, testserver, web api, .net 5, dotnet 5, .net framework 5, dotnet, .net
Id: 7roqteWLw4s
Channel Id: undefined
Length: 22min 13sec (1333 seconds)
Published: Sat Jul 06 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.