Distributed .NET Core (DShop) – Episode 14 [Consumer-driven contract testing with Pact]

hey welcome to the 14th episode of distributed intercourse it's bitter end Derek we have had some short break but we are back again and today we'll focus on the topic that we mentioned the last episode which means that will basically continue with the testing our app and in this episode we'll show you a little bit different approach that you might not be familiar with or maybe you just heard about it but never actually give it a try so the idea behind what we're going to do today is called basically consumer driven testing right yep so what's the what does it do what's the consumer driven testing about what we do what do we do about it yeah basically yeah as the name says this this test will be primarily focused on the on the consumer and his expectation about the contracts basically what we are going to do is to make sure that that we have the contract between different services because we assume I don't know whether we actually mentioned this in this whole series but our primal approach about the messages was that we had one shirt project in called messages and we had we kept there every message that we actually exchanged or shared between across all across the services so we had their commands and events and so forth and as you probably know now we have a slightly different approach because every service has its own local copy of the message and that's of course that was great for us now and has some advantages and disadvantages and one of this is that because we don't have one shirt dll all across the services there might be some inconsistencies between them and of course if we we could have some versioning and so forth but it's still we need to it would be cool to be sure that we actually keep up to date with whole contracts for every single service and that's what about what's the part is all about so basically what we are going to do and this is a pretty cool picture that we found on the internet so basically what we're going to do is we're going to start with the consumer so the consumer itself what we're going to do it we are going to create a mock HTTP server which will be some let's call this fake provider and we're going to do a real request to this mock server and we will mock the response that we are actually expecting so we're going to say that okay I am the consumer of some message and I want to this message to have that set of properties that I need and as a result we will generate a small JSON which will represent our part so this this file this JSON file will contain the whole outside the consumer expectations about the contract so this is what we need to make this consumer work and that's their face number one so this is we start from the consumer then what we're going to do is we're going to launch our provider so some service that actually provides this data and we are going to confront the file with the actual with the actual HTTP request to this provider so we are going to say okay this is the pact now I'm going to do the real request to the API endpoint that actually is a provider in this packed file and we're going to see whether the data that comes from this API match our expectations from the consumer if so then we have a the depart is verified successfully right so we have the match between the consumer expectations and the provider itself and the data that it provides if now if if there is no if there is no match between this data then we have an issue right and we need to correct this one or another so that's the whole idea between the part itself and the park foundation this is the whole concept and of course you can find the clients for this technique in several different languages and one of them so maybe you could open the part on your website bhakti-yoga where we can park IL great yeah all right so by default is rather early directs you to this Doc's patio this is the whole foundation you can look for different keywords here was this all about and basically it was written in Ruby but there are different libraries for different technologies so you can use it pretty much anywhere yeah and there are there are some samples and some I think that we are using what we're using is target net right it's it's the official one the official library from the Park Foundation github yeah so the LCC is three hundred forty forty to start so it's pretty good we have the whole sample how we are going actually to do you know download in naked packages and how to create the particular components that actually needed to run this packet tests so this is pretty cool I think that we had some issues with following these steps but some kind we may get what I mean at first you have to be careful about the paths of for example the tax files yeah and also be careful about your operating system because you have three different types of the park libraries whatever using Linux Windows or Mac OS but it gives you this warning or error that you should install another package and it will just fine and 1k but is that well fact is all about really the HTTP request/response testing so yeah if you want to do some you know RabbitMQ your message queue testing then you should do some to some you know other technique you do it in a different way just like we did in a previous episode or maybe looking into some other libraries that will able to do that yeah just so yeah keep in mind that will actually do this for just for get requests right shall we start yes that's going to be okay so just to make it clear what's the run tree roadmap for this episode because this is crucial for understanding so SPO mentioned the part is consumer-driven so we are going to start with with this part we are going to create first the mock HTTP server that will be it's necessary for generating this request then we'll actually create some tests that will produce packet file so this is the first one as I said so this will be the consumer part and then we will use this generated file and we'll just move to provider right correct yes right so all right so we need to decide which service is going to be the consumer and which one is going to be the producer or the provider so we can treat the discount service as a consumer and if you if you open this project you can see that we have these services and have some sort of like dependency between the discounts and the order service so you can find here we have this area probably even handler and it's using the order service in order to get the order order DT or this is Atiya for the HTTP call so the order service with the provider and the discounts with the consumer when I mean when talking about the park hi oh yeah in this case of course we just keep in mind that that was some example to show you the console and the Fabia so this actually you know breaking the contract would not make any damage in this case but just imagine that we have some business logic here that uses some property yeah yeah so this is the consumer and the provider would be in this case here or the service so we have the orders here okay yeah so we're basically starting with the discount service as we start with the consumer first yep so shall I create the project for this yeah but I think we have because we are it's the one from the previous episode so yeah let's let's do another one so it is do some sort of they'll be the X unit hopefully we have some you need this project okay I think oh that's pretty cool so the D sharp what's the convention here okay so the dish of services and discounts and maybe let's do some park tasks parked tests yeah and just change the directory let's put it into the I think it should be test directory yep that's kinda yeah that's we would have all right there is just cool yeah okay so here and I'll change the framework yeah it's interesting oh oh it's here okay okay yaks you need coke great actually this is I think this is the first time I actually created a project using the rider not the dotnet CLI it's kind of weird yeah it's alright so at first we should I think that we just start with the Nugget packages because we'll need them so that was the part net right that's right and for the mac OS will install the OSX version but again you can either basically install the free packages for iOS or six Linux and Windows and you know depending on the operating system it will you know use the correct correct one so yeah there will be no like conflicts between different versions right I'll just remove this because to me okay this is taking way too much time it's kind of weird yeah but this is all right so we'll start with the with this mock server right so this is the end the first thing okay so basically create a new fixture right class fixture yeah okay so how should I call this you have some cool name well so we can call it something we like since we are testing the the discounts being the consumer so maybe something like discount service mock server or because it's going to be the mock right yeah but this is the mock for the orders again ah right so order service box server or something like this yeah whatever excess maybe order API mock server or okay maybe I could just the Mafia yeah that's all right so we have this class now so I disposable just to keep in mind oh yeah and the reason for this is because that's the way of dealing with with clearing the stuff in X unit we don't have any dedicated cleanup methods or a teardown yeah so simply you need to implement I disposable pattern by your own to make sure that once we actually run this mock HTTP server when we are done we want to kill it and produce the file as a result so of course I will need to generate the whole Wow that's kind of cool that was cool implement disposable pattern I expected some you know some pre-exists a proper not dispose disposing yeah yeah that was yeah disappointing okay so make it just to make it quick so we'll start with the disposed so typical way of dealing with this you should add the put the underscore here just to be consistent you know it could emit false but whatever yeah but just to make it clear yeah okay you should know if you're watching this you probably know that the default value for boo if you do microservices which I should probably know this anyway yeah but just to make it you know clear okay so dispose yeah oh you should yeah it's right over right this property so bull disposing of the first no oh sweet okay so okay so let's just get this no just post Jesus wait okay so disposing okay so in here we'll do some stuff yep now let's mark it as dispose equals true yeah and here I don't know whether we need some GC suppress finalize here probably not yeah alright so this pulse yeah we'll get we'll get back to this soon alright so and for now we need in this fixture or mark or whatever we will need something provided by packs to actually create this HTTP server and will need actually two things so first one is I think that maybe will be private private three down ladies let's make yeah can be private yeah so I need the pub builder right yeah builder there was the interface that I think we could also use not sure whether there's a difference but we can still today yes so let's call this part builder we're all right this is the first thing and we'll also need and I think that this could be also okay something like this so we need a mock provider service yeah so let's call this here okay so having this we will create a constructor and inside we will instantiate the Builder and in the mock service itself okay so let's start with the with the builder because we'll need and we can instantiate this and if you see it's some sort of config yeah we have this packed config that it needs to maybe it doesn't need doesn't have to be provided but but we will there are some formation about the packed file location and there are some default values that we would probably want to overwrite so let's first create the packed config and see what we can actually set here all right so maybe maybe let's serve the version because we just want to stick to some specific version yeah and we'll use the 2.0 by default this version is I believe this is one point 1.0 but there's some changes according to the configuration I believe so we'll stick to this version because that actually worked for us yeah since this works so you know what it is but I'm not quite sure what's the part you know difference between the particular versions what we would like to actually change is the park tier so this is the location for the box files yep for the park files so we'll need to choose something and I don't know where we are we're going actually to to put this may be all right maybe outside these you know on the same level as the directories of the github repositories or about if we can do it like this or maybe we can just keep it within our pocket test test project let's just create a directory here and here okay right we need to share this one okay yeah so yeah maybe let's put it a little bit higher yeah and the lighter will acts we'll get to this part because this is a little bit more tricky okay so I need your help to count how many levels I need to go up yeah so you know starting from the bean debug it will be me think so it's bin-debug then up to the testing thing is going to be at least five or maybe six I think this is SP and the project think it will be five I think it's just something like this and then parked let's call this directory alright and we want to keep the pacts within the discounts or one one one of our above one about one two three four yeah should be five should be enough I think yeah I will see you'll see in a second I feel I believe alright so this is the place that we're actually the generated file will be put into and we can also set the set the login directory for the logs and for for this particular case we can call it we can put this in a in a pin directory because will not focus on this that match I believe that this is actually the default but I'm not quite sure so this is the configuration that we can pass this to our builder and this is the first step okay now we need two simple things first we need to say that this is the that we are going to have a pact between two to service one is the consumer so we want to pass the consumer name and basically based on the names will generate the pact file so the packet fact file name Wilkins will consist of actually a consumer name and – and the provider name so let's call just discounts as you can see our discount in this case because the discount server service is the consumer and as you see we have this has packed with methods so we'll call this or this is this is some serious fluid API here yeah yeah yep so this is all we need for now – as for the Builder and we'll still need this provider service I'm not I think that way we will need this but for now I'll just make it private so what provider service all we need to do is to actually get the park builder yeah I mean everyone did this one will basically need the URI of the service but oh I think we'll need both so you can make it public yeah for this we can just pass the port that's correct but I think that we'll need the provider service to be public anyway property yeah that's right because we'll be using it later on right yeah I thought so so okay let's just make it public for now let's just make it read only and you can change the name as well yeah okay cool okay yep so in here we we need to as you see there are lots of overloads here but we'll just stick to the overload that actually and then we'll just leave the default values so we only need to pass the port so in this case our port is gonna have to be nine two two two and this is that the not some random port or something even though that the order service itself is hosted on some I don't know five thousand three or something III don't remember this is not the port that will actually the order service is using this is the port that as as far as I know this is the port for this for the Ruby server that will actually use for the mocking so the this number is not something that you should you know came up with just simply stick to the nine two two two so this is it in this case we'll have some we'll treat this as a fixture will inject this into our tests just like we did in the in the previous episode so we will when we look this picture will be created will actually create a mock service that will be hosted on the localhost nine two two two and last one thing just we need to get back to the dispose pot disposal disposable pattern when we actually are disposing we need to generate the close the box over here and generate the part so for this case we'll simply use our builder and call built that's all thus line that actually does the job cool all right so since we are good to go all right so let's get to the actual test and let's call this I know orders packed tests or order practice orders okay yep all right so we'll start with what would be a class picture I believe yeah we do inject this class fixture and we call this older API mark and we can oh no I can't so just create a constructor and we can inject this it's called this mock for now or maybe older IPI mock just to be sure all right so in this in here we'll need some something also to set up and we'll need I think we'll need the mo provider service for sure because ooh I'm using this one and here this can be definitely the read-only yep yeah right so let's just assign this my provider service equals API I maybe call this fixture because in this case not a fixture yeah well not yeah and there is also some magic line that says that we want to clear interactions and that's just to make sure that it will run this in parallel that will not mess up with some weird interactions that we are actually doing so this is for we need for now so we'll need this mod provider service and using this we will actually create the actual tests now yeah okay so what we are going to test well it just says that there is an order that we can retrieve from the order service right yeah so what's the maybe just let's go to the controllers and show this we have some API for this this is this one right so the orders slash in the end we have ID and we expect to return order details DTO so if we go here you can see that we have the order do we have some properties and we also have I how can I get back to the previous oh here okay and we'll also have the customer DTO and the ienumerable of the items itself so I don't know whether we'll actually focus on all properties maybe just some no I mean we could basically get the ID or something else or actually make it dynamic yeah it's not as important yeah we'll just see what are some properties from here are actually much right so do you have some name for this today me yeah this test so it's call it like maybe give given valid order ID orders should be returned or subpages okay should be returned right and let's just put the attribute called photo called so this is provided by the X unit all right so now this is the actual testing and now that we get to this to the actual we are creating this whole as a assertion I would say so if we go to the mock provider service we can see bunch of a bunch of a couple couple method us we can actually use so we'll start with D and this is a very similar with the maybe not similar but some sort of BDD when we actually describe what we are actually doing so this is vertical think about fact that I would say that from my perspective you know describing the test like this like you know given and some giving some short description and what we are actually expecting this much easier to understand especially for the developers are not familiar with testing itself you know rather than just for the or for the business guys you can show them the yeah test impact and they'll be very happy about it yeah yeah so this this is this is cool thing all right so let's start with the given so yeah I don't know maybe what should we write you wrote the guy from the from the from the naming all right so what what we are given well maybe you are just given the an order or given an existing order all right so let's convict or maybe just order over maybe okay existing order this thing order right then we have upon receiving methods so do you have as you see one parameter which is description so we can just something like get request to retrieve order yes yeah order yeah ordered it is something all right now we have next part which is wave and the wave is very simple we just pass the provider service request and we just specify what the details about the HTTP request that will actually do so first we need to specify that this is actually get request because we'll use this for retrieving data and only think we need to specify is the path and this is not the full path this is just the endpoint so in this case that would be just orders right and then we have some to win to start with this slice or net I think so yeah okay it's all orders the plural and the order ID right yep I think that we can this is actually interesting because we don't need to get some some existing we'll need some existing order actually I think for this case yeah so basically this is the place where you would expect your API to return the order and you have to keep this ID some are hard to read or create order before you invoke this test yeah because this is yeah but basically we'll show you how we can actually mug this I may be arranged this when we go to the providers but for now let's just that's actually good question so we need to create the order first I think that for if we don't have this script for now setting this app I think that for now the only only thing is just to create the order itself yeah do you have any orders in the database because I don't think so now yeah maybe just just you know for now just I'll create something and we'll try to generate this at the at the end because that doesn't matter we can just simply rerun this test and create a new part file and we'll just try to run everything at the end yeah I mean what we could do we could you know just put something into database that has this ID property or create a new order go for the whole API flow whatever now let's do some arbitrary yeah that's a pity because because the order because the order itself I need to see what's the worst offender orders and we have was the get order here alright so we are okay we have the local copy of the customer because I was afraid that we'll need to do something but this is kind of yeah maybe just try this because we'll just forget about this – we'll just focus maybe on this one right okay yeah so some unexpected Jesus Christ wait give me a second we have Oh have some issues cannot connect what unreachable right needs to see whether I have the darker but this is running that's kinda ok I know but this is the version that actually does not expose the pores because those for the integration tests right alright so I will also need to to docker those then to file Mongo AB detached mode great now I have to mongos E or not or I have I don't see only only one ok no wait just down this dr. Campos yeah I was wrong one actually yeah so let's down this for a while where's the fire responsible for this okay I'll just told manga rabbits yeah that was yeah that was something yeah it's think it was it was creative yeah just I'll just peel this like this because I want to look for this file for now right that was pro as hell all right now let's make it work docker PS yep now we have manga that's actually for watch this let's try ugh sorry I I don't have this on let's do it like this and we'll need the database write the name if it was just orders – service like this yeah yeah I think that we can just simply see whether this is actually yeah I'm pretty sure yeah I know that was a console yeah okay and we need to create the orders collection yeah orders capital all or not think with the capital oh okay so instrument and T do you have the the.net you UID enjoyed I mean option set I have no yeah okay it's correct so let's just insert a new different with the ID so it's underscore ID yeah we need to generate some some goo it right you can go to maybe to it generate or calm or whatever that's embarrassing that we actually didn't predict this but yeah maybe I will just put some description yeah but this out can create a mock data yeah I think you need to put this into this nu UID before the before the volume yeah and maybe let's put there some some arbitrary value what do we have in the order and we have okay so we have the customer ID maybe not maybe items count and total amount or items count and status all right I think comes in status right let's make it count let's say complete computers maybe like this okay yeah yeah we have data all right yeah so god bless the non schema databases because otherwise that will be pain all right so this is the actual now we can just copy the value get back to our protesting here so in this case I don't know whether we actually need to interpolate this but maybe to make it clear just an order ID in this case and we'll just keep it oh Jesus Christ why is that okay just to make sure that we're on the same page just do them shrink interpolation all right so this is the path for getting the order right so we have given a parasitic wave now we have the next step what's the response that we are actually expecting from this endpoint so we have the corresponding methods which is will respond with and we need to pass the provider service response so it's convention is basically the same so as we describe the requests we want to describe now the response the first thing is of course that we would like to make sure that this actually turns some 200 note some 500 or something else then we have some others yeah and so let's just stick to the basic the content-type yeah and it's the application slash Jason semi column charge set equals utf-8 okay all right and the most important part which is of course the body and we will I think I forgot to add the dependency dependency up ah all right right because we need do I think that this is yeah this is the dynamic but just to make sure that yeah I mean you could you know create your own DT or here is the dynamic whatever or some anonymous type but this is okay anyway these free fields the ID status and the items count right so the idea we already have above food to do the guiit parse there is some constructor that actually accepts the D I not sure I think just Dooku each part is just for the curiosity maybe race actually if oh there is nice yeah we know it's using the parse alright so we have the ID that I just got was for items count was for and the status was completed all right okay so this is what we actually expect okay so that's the part that we actually so this is the whole mock right this is this is a little around this now even though it does nothing yeah this will pass but this will I figured this this would probably generate something let's run this let's see I don't have to try this to actually run this this should obviously pass because you should probably start just the practice okay would be also cool to see whether we have our parked something somewhere so let's open this I'm sorry I need to go on the other level I think yeah so the tea shop yeah and just give me a second here alright so I have to discount and do we do see the pockets should be in the route or yeah I wanted this to be on the same level as the these directories I don't see now and that's probably because we didn't make any call because okay generating the generating this is still I would say this is still the arranged part right maybe just to make it clear this is a range we just want to prepare the mock server and now we can prove this in in a second that this actually is just preparing AdMob still mocking this but we'll need actually to create the HTTP call to to make it work so just for the simplicity sake just let's create a HTTP client I don't know do you know whether you can use the client factory in the tests yeah I was wondering whether we should inject the I HTTP client factory yeah yeah and here we'll need the access to the URI but can you get the URI from the provider service or do you have to expose it through the fixture oh yeah we'll need to add something okay you're correct so maybe not just at here public that's the string string yeah and how do we want to call this mock URL or something what host URL yeah or service URI okay we're in a mock way maybe just yeah and this is going to be localhost and we need to just provide a valid part which is nine to do – mm-hmm maybe just extract this – all right yeah I'm very inconsistent with the conventions but this is how it is so this is going to be the end this is going to be the service right okay and we had this okay and just do is this in this string alright now we can use this so we need to do to get a sink now it's typical HDPE stuff you should be familiar with this public oh it's part of the fixture so okay so I need to just make the read-only field for the URI correct make it a string yeah service your eye all right so let's just copy and use it here so that was the house part and now I just need to do the orders and the all the right right and finally with the Jason visualize it and assert values yeah so just do the response and content and get sorry read T or this string yeah I'm looking for the synchronous streams that's it's not cars it's order yeah details maybe yeah it's cool so Jason comfort and then we have the serialize object to the order details ETL and our Jason and final the assert I'm wondering with the whether it will work or not I I have no clue actually and this case we could we could do the same like we did in the previous episode so to use should Li but in this case the assert is just to do the assert because we'll mocking the server anyway in this case so I'll just make it order details and let's see and say ID and this is yeah new GUI you know maybe maybe I'll just wait because that's kind of embarrassing that yeah just make it good this is fine here I don't need this now this is yeah we are like real allocations less it's nice yeah yeah all right now we can see whether this actually yeah this should still succeed and we'll see whether we have some yeah so we succeeded now we need to go and see whether we have oh we have like okay so nice we yeah we need one yes I was correct we need one more yeah so let's delete that's all yeah you were correct so let's get back here and put just one more level okay and they rerun okay I think there should be maybe there is this library like this let's say dot and then you have five levels above or you know there is an extension for the visual studio code and this is called path intelligence and when you type dot you this actually shows you the current director you know the current directory what this contains so will be much easier to have some sort of this extension for the rider it caught it's I think that I have this installed maybe I'll just show you yeah of intelligence so if you're working with c-sharp individuals to code this is ordering with the JavaScript and you're just using some relative paths this is the way to go okay so mmm yeah we should go see whether we have this part yeah so this is the pact between discounts and the orders so we can see what do we have here and yeah and what do we owe this is actually kind of cool case as you see maybe okay let's start with the details we have the consumer name discount provider orders that's what we actually provided provided in the Builder and when we have the interactions for now we have just one because we specified one connection or maybe one marked endpoint of the description provided state some discrete some details about the request and the response and this is kind of cool you see even though we didn't specify it and we created this call this actually does we have so have some default values here yeah so this is which is pretty cool that yeah this it still have this alright and we have also the the diversion so this is the the part and one more thing I think it would be cool to show if we put the breakpoint here and I'll just be back and let's see whether this will actually work alright so we have to break point if will to try to do the localhost 92 to that orders dot this oh sorry this one yeah you see that I see that this is actually hosted so you can access this run while your tests are running so this is not something that it's just you know made up this leaves yeah that was the first face that was a easier part I would say what's the next step so I need the provider test right so I also create the and the separated project I think for the for the order right okay just – okay this is the D sharp services order sparked this all right great okay and I will just start with the same thing so adding the package oh that was quick in this case and just add the reference to orders here I'll just delete this alright and just clear it up okay so what's this the first thing we need to do on the provider side so I think we need to do the fixture for the provider for the for the provider I think that we don't need the fixture itself because we'll just run this Yeah right I mean other fixture basically yeah we can look at basically start with the test because just with the tests I think this some order API test mixes orders now I for this case this works but I think that we should also distinguish some catalogs on consumer and provider because you know order service can be you know at the same thing can be a consumer for some data and the producer for some other services so just to to make it to make it clear it will be worth to distinguish some catalogs but for this for this example for this demo it's it's fine right so create this and I think that the same story as we did in in the previous so we need to add this possible pattern I think right yeah only to clean up so you can basically copy and paste the disposable implementation yeah generate this post pattern well this is this is this is huge yeah I'll just copy this all right for now just leave it as it is okay all right so what we'll need to do here okay so basically we'll need to initialize within the constructors as we exit the URI of our of our order service and we also need the URI of our Park Service and then we able by now setting up the path verifier and providing the voice config the path through the park files will basically run the tests based on this Park files yeah so maybe yeah I'll just generate the constructor first okay so for now I think that we will just need the the provider URI right so just get rid of the Park Service itself so this is yeah just create yeah well basically the provider rewrite maybe let's stick to the order or this API you're right arguing are we go are we going to use the 5,000th I think what is 5 for orders or 5,000 doesn't make a difference you're right it needs to match the the our uri from the from the app settings just what's the always service you're right okay just to make the same so the service URI and the reason for this is because in this case or maybe we don't need to know we yeah no we need because we will actually use this and the parked library will actually confront the part with the our running server and it needs to know what's the service you're right right because otherwise we would get some 502 or something so that there was no connection established that's sure yeah so let's just say that this is do you remember this yeah let me tell you so the URI it's for at five thousand five and so the other thing is that we'll we'll try also to to Randy the the whole sir the whole application for this particular case so we'll need the web host right yep so maybe just I'm gonna need to create yeah I webhost like this and this is where this is the place where you can basically override your startup from your API that you are about to test whatever by you know creating the test startup or overriding the web host builder yeah and and of course we could do this much better and use some test holes like like we showed you but just to make it simple or application factory from the ASP deathcore yeah so the stuff that you know from the previous one but this is just you know just not to take into too much details because that's already for some of you I believe this is might be complicated right so I just use your else I'm wondering whether we actually this is because we might use this we'll still need to start our API but I mean for the common line right so basically with this we should should not I think yeah we can we can use it later on where we mentioned what the what the provider states is all about right for now we will not be Emily maybe maybe you should just yeah this constructor empty yeah let's just keep the service you right here for now just you just keep it there and that's it yeah okay okay yeah yeah will around they will run the API from the open CLI that's that's fine all right so let's create the actual test yeah that's another naming challenge for you all right let's make it since it's going to be only a single test right because we'll be yeah we'll be verifying the PAC's file so maybe they're just it's parked file or park should be verified okay okay so for this we will use because we need to verify the park and there's some type provider by the library which is called the park fire fire who the best yeah and if you see there is also some is the config required yeah packed very fire ok and can we can we pass the coffee just default coffee and extended later on yeah ok so let's let's pass the default one and yeah yeah so for now I don't think that we need to when it just the service provider and the file path yeah so here we'll we'll use the provider name which is the orders and we'll set the show will pass the uri to have defined above service you're right okay now we need another we have another extension method all our spa knows with yeah so discounts to discounts and now you need to copy and paste the parks URI that's correct and as you can see now that's a good question because they they named this method parks URI and they the name the argument path of the file so the question is because you know in a like a real-world scenario most likely you won't be sharing your park files using your hard drives between different services so I can imagine that party or I could be something like the web URL yeah I've you're correct and this is if you go to the github this day there this is here you will see that just need to scroll to the proper thing yeah if you see that the park to your right except this could be either the disassembled about the location yeah or the HTTP and of course this is what I wanted to what I wanted to talk about because for now as you as you see this is kind of easy right because we just generated this file and we put this into the parts right and here but we would face the same issue that we had with our camel package that this would work on the local build but once we'll try to actually run this on up for some continuous integration will face this challenge that we have we don't have any shared directory between different repositories right and since we need to run this both on consumer and the provider side we would simply have an issue so to so to overcome this you can instead of generating and putting this file on your hard drive you can actually generate this and put on some some endpoint that is available and instead of you know on provider side instead of copying the the director like this you could simply use the URI that would provide this JSON for you so this is the way to actually expose your pacts to public and this is especially handy when you're working for the micro services yeah did you to provide you the whole whole path to the file not just directory yeah this is correct to me this is kind of weird because since there is a convention that the name is generated based on the consumer and the producer sorry consumer and the producer I think that they could do this but yeah even though we need still to okay I need to know whether this is the it was discussed our shoulders so I'm not typing right it's right and the final call it's to verify yeah so this is the word that what the actual testing happens yeah so this is this is the thing I've I guess yeah you need to market with the fact attributes oh yeah and what can we start the API now and see what will happen yeah but this will fight actually okay what is the the reason is that the parked itself would have this issue with the camel case because the asp.net car when we'll actually called it because for now we'll just call the the actual API the data will be returned with the camel case while if you go to the parked file itself you see that we have the passport case for this and there is some mismatch so we need to override the settings for this so we need to pass that we would like to so we can either change this temporary on the on the orders side on or just try to change the behavior with the packed but honestly I forgot to check I think that was pretty out there some JSON serializer default settings using this overload okay so let's make it on the consumer side and change it right that it makes more sense rather than messing up or so those here I guess and that was we here yeah that was here the second parameter good and we want the camel case or the bus we would like to accept the wait well like the comic ice right okay so it's you need to open the the open the brackets okay right and I think there was this sterilizers property or we already have to call the ad sterilizer sorry maybe you're right maybe you have to open we have to do the dot and there just see I don't remember this actually said teen what's the setting so that's right yeah and don't something like seriously binder no that's that's can you check this yeah oh wait okay oh contract was over oh yeah right yeah it's been a while since I sorry camel case prepared two names contract is over yeah the first time yeah this is good yeah whoo that was something all right let's try to rerun the test and see whether we'll get the correct packed file if some if so this is this is Wayne come on alright this is green that was the easy part yeah yeah that's correct on yeah all right so we have the correct part for now so the only thing that we need to do is we need to go to the DNC tea shop services orders here right and before we run the test can you open the localhost 5 or 5/5 505 such order / ID to see whether we'll actually get the order yeah okay I was afraid that we have some nasty errors but this looks surprising so copy the order ID you can copy the path oh yeah so maybe just instead of yeah yeah should be enough I think ok we probably don't have this value in the enum could be can you look at the older status enum because that's probably the issue with the civilization or its yeah but we see char does not support the drinking no it does but the not velocity sorry the order okay sorry see can you go to the order status where's the other status here okay yeah f12 we have completed can you touch can you try can you try this one with the capital C maybe you know it because since its using mama driver maybe it it should use the strength but maybe it uses the camel case so it's not trying to do the in impairs ignore case so changes to the completed with the capital C if not then we'll have to use the to volume but it should work now yeah so what it yeah if you take a look at the get order handle it probably tries to create the customer and D and you know the the orders list so can you go no it's this o sign that's right no that was fine I think can you go to the gate order handler yeah yeah so here's the issue it tries to create a new customer video and the new items but these are knows right okay that's the way to go yeah yeah just start the app yeah it should be fine and we did we did this because we can it's all about providing the sample yeah and sometimes this issue a lot that sometimes making samples you know just takes way more time that doing the regular data this is now it's still gonna be now what the hell perfect name source that's something it's a typical another reference Oh these status is now and the items is also now made the status is not sorry the items is now items count because it takes the items that count oh sorry this would be knowable yeah that was before right yeah I think for yeah it was for those for total amount was also we don't care about to that amount so but yeah this is cool yeah since we didn't have we didn't prepare the actual order we have to do this nasty stuff yeah forgive us but the first try yeah would be I would be boring if we just I would work for the first time so yeah I said you need to alright the settles completed yeah but else was the default of the completed no it wasn't okay okay alright so we have API running they are going to confirm this with the with our part right yes just to list yeah we can just quickly see we have ID see this maybe pull it right this okay sweet control we comment be come on be great or control-d ha yeah alright so this seems okay I think 0 0 yeah in theory this should work now we can go to the test and this is not this test this is that's right mm-hm and see whether this will actually work so run did it did okay just started yeah yet so this worked all right let's just try to break the can you change something unit in the park file maybe let's make five instead of four maybe just said that we had some old version and this was called I to count instead of count maybe let's call this number haha yeah so someone did some refactoring this is awesome because this name was better so if will now run this just for the provider because we didn't have to generate this yeah it fails so the verification failed see output for details let's see and we have no details and that sucks but but yeah there is a there is a quick fix for this and I think this whole episode the buzz is about quick fixing something but this is really yeah this is a quick fix actually if you remember we have this conflict so let's just extract this call this I know config I think that we call this before pact config so let's just think the same name alright so we have this you will see we have something like out tutors yep and this is I believe I inaudible yeah so just create a list of this and we can create our custom output her that and the reason for this is that there's some issue the X unit as far as I know and in to create your custom output err to print the data to the console but this is very simple or anywhere else that you can think of did you spotted that I did less typos in this episode I'll make ya at practice yeah every day I practice to not embarrass myself anymore I screamed out pooter I'll put her yep totally emigrate that's right okay and okay why is complaining I did type of renamed to now the autoblow name is fine I don't know why right just don't get confused with different a space of this interface yeah and we need to use some special interface from the X unit right yeah this is I test out a helper a tactic helper class is this Jesus all right I'm just you can utilize it yeah here or just because I will be injected by the X in it that's right sorry yeah okay and just line the line this is whole magic I believe this is this is the whole magic so basically we have a wrapper on top of the X in the interface to just call it method yeah okay and we need to inject this out to helper for our constructor in the above just create definitely this episode is more about writing all these fins around tests that actually did the actual test and that's awesome yeah it's still I believe this is something interesting maybe for some of you so yeah but I mean why does it have this holds it up completely you can basically focus on writing the packs and you don't need to write any yeah any test cases on the provider side you just verify that part which is cool this is a typical thing right you basically first start with this whole helpers and other stuff that actually necessary all just helpful when you know it comes to testing then just focus on writing the test so this is this kind of pity because we have just one test actually or maybe one part to verify but we still had to follow this whole test that is you see we have some nice nice output right now can you run it for the CLI as well just do the dota test yeah on their CLI level dish dish shop services she tests practice and dogmatist just make it big that's going to be yeah yeah as you can see we have some pretty nice description what's going on here and yeah this one failed right or not yeah yeah so couldn't find a key items number so this is really cool yeah so this actually yeah we see that interaction it's it's not telling you source is now or source valuable sponsor whatever is actually meaningful yeah but that was something yeah that we expected something we help and have to smell the scripture so even reading the test it's it's it's better right because you can just read it and let's pick the past let's fix the pact to make it to no use the items count again and let's rerun it rerun it so it passed us okay right yeah it was got we're on the test yeah just prove that we're not cheating there's no this is some disability can pray you can give to the business people yeah no just case it's not that fancy just yeah it just passed so yeah so you can just you know show them I just passed it just passes and and inside yeah just create some assert true true I think this is pretty much it or maybe just wanna thing but I don't this is about the state or yeah I about the state but maybe just let's talk about the concept yeah maybe just show the how can i you know remove this please okay just close this and here okay so I need to go to the particular this is okay so the thing is that in some cases you might want to to some arrangement before you actually call your provider so the we are now talking just about the calling the provider side so very verifying whether the given parked file matches the data that comes from our API so for some sometimes maybe you need to you know some insert some fake data into your database that would be helpful in our case or or do something else produce some files whatever in this case you can create some sort of middleware and inject this in your using some web host like code set or just create a separated startup class that will include this middleware and basically you would accept two things so the consumer and the state so before verifying the pact and calling the API the pact will do the post request to give an address and this and will and will send just two pieces of information what consumer actually calls the provider and what's the particular state and the state to be clear is what we included in I need to find it discounts what we what we pass in the given so in our case before we actually call the orders and then this guiit we could create the provider state endpoint and before calling this api we there will be some post request with two pieces of information that the discounts this is the consumer is now testing the state existing order and then you can create some middleware that based on that could you know can you could as you see can create some dictionary that excels the shrink so this is the this is the state and some action so in this case could be as you see after serve does not exist so in this case in our case that would be there is an existing order and in the lambda we could create some method that would insert some order into MongoDB or something and this is so this is the middleware and this is the whole idea and if you go to the configuration you can see this is the line that actually does that so provider state and you just need to create the create some endpoint and just respond to this so this is the whole idea about this right mmm yeah and yeah wolf in D the problem actually orders API test you would have to you know set this put this vid where and you know credits provider state yeah it would work so this is why so this is why at first we start to type in a web host but then we realize that we don't need this because we are not using T provider set but if you want to use the provider state you could basically use the for example I web host or this web application factory coming from MVC court testing library great start your provider provider their uri provider service and setup the provider state put some middleware that will force up return maybe you know the order for your some girls on some test endpoint and use it yeah yeah so yeah it's will already have like an hour 25 minutes so maybe 30 minutes so it makes no sense to make it any longer because in our case that was not crucial and this kind of simple and well explained in the pact net on a github so yeah that's it I think yeah it's maybe just to sum up what actually happened because that was kind of kind of complicated so we started with the discounts because we as we mentioned this is the consumer driven testing so we started with the consumer we created this mock API and we specified that we want to where where we want to store the part file what's the version and so forth then we actually instantiate that we want to create a provider server and we specify the port just keep in mind that this is not some random number this is actually this needs to be nine to two to maybe there's some we can change this somewhere but I as I believed it was some Ruby server that actually ran something so this is the hallmark then we use this in the in the tests so basically we said that we have some order that we specify that this is a get request we specified the request and the expected response and running and then we actually made the call to the fake to this marked server and as a result we received the part file and that was used on the provider side which in our case was the order service which simply took this using this path and verified this against running dotnet application so on the provider side we did not use the mark because that would make no sense the customer could mark this because he knows what he expects he don't care he just goes in that he just presents his expectation and this is the providers responsibility to actually fulfill this so provider had to run with now mocking data something just yeah okay I think I think this is it right yeah that's it so thank you for watching this episode this is all about testing will probably not talk any more about testing because we've already had two episodes so yeah this is way too much yeah everyone tears in the production in the micro-services anyway so yeah okay so thank you and see you next time see ya

4 thoughts on “Distributed .NET Core (DShop) – Episode 14 [Consumer-driven contract testing with Pact]

  • Very nice, loved the live coding guys! Would loved to have followed along for the creation of DShop.Common library 🙂

  • Thank you for this episode! Honestly I haven't understood what do we actually test with such tests, for me it looks like we are testing that pact can serialize and deserialize objects. It looks really weird that we are preparing some test orders data in discounts service tests and doing assertions in orders service tests. I thought based on your earlier videos that services shouldn't synchronously call each other by http calls and their communication should happen through message bus, given that there's no need in such tests in well designed application, am I right? 🙂 When I need to test some external dependency I'd rather use simple moq for that, which is much easier.

Leave a Reply

Your email address will not be published. Required fields are marked *