Easy Angular Unit Testing in NgRx - JavaScript Marathon

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
good evening everyone all good morning or good afternoon depending where you're located now welcome for another JavaScript marathon this time we're going to talk about unit testing and Yorick's first my name is Frederick Beck senior software engineer at this dot labs you can find me on twitter using the handle mentioned at the bottom of the screen and please don't hesitate if you have any questions feedbacks or concerns of course we couldn't do all of this without our sponsors our first sponsor for today is digital apps we are your partner in modern digital transformation we specialize in mentorship consulting training and staff augmentation for enterprise organizations you can find more this off labs.com or you can send us an email at hi at this dot for the code if you're also having trouble keeping up with the constant evolving technologies and we want to bring your team up to speed with one of the latest technologies digital apps offers personalized training training programs to suit your organizational needs and surely you and your company stay up to date on the leading edge you can contact us again at hi at this dot let's go to set up your complementary needs assessment apart from this JavaScript marathon we also have our online meetups and one of them is the angular meetup which is always hosted the first Thursday of the month and the next one will be May the 7th and which will be about the state of NJ rx basically this is a partnership with normal and we will have Brandon Roberts Wes Grimes Mike Ryan and Alex or Cusco from the ngrick scorer team speaking about the state of NJ X you can register on angular madoka we also have a react meetup which is the second Thursday of the month and the next one will be about the state of react with some of the react core team members and also a view Meetup also online which will be the third Thursday of the month and you can adjust it on you meet up our next sponsor for today's introduce --tx you can learn how to build better faster angular apps with ignite UI there are hundreds of ready to use templates angular components charts and controls to make your development experience positive you can write UI is a developer's choice for angular and you can check out our sample apps and try ignite UI for angular for free at the link mentioned at the screen and other than that ignite ignite sorry infra gistic is also doing a giveaway so give us your favorite thing about this session and tweet to add digital media and at registers with the hashtag JavaScript marathon and get a chance to win a one-year license for ignite UI for angular alright unit testing with ng X so today we're going to talk about how we can test how we can unit as some parts of NGO acts such as reducers selectors effects and components that are making use of the store we are not going to go into details of how we set up ng rx and stuff like that so we're going to start from an existing and your X application which I will give you an overview of and then we will dive into testing it so first things first how does the application look like we are going to work with so basically if anyone had ended my previous session that was also about TV shows this one is again about TV shows and basically I have an application that has been all shows and a favorite show section we can favorite shows by clicking favorites and they will show up in the favorite shows section and we can click unveil it and they will be removed from the favorite show section we can also remove them and then the show is removed this is a very simple application and it's using the NZXT store to manage all the actions and state and stuff like that so the idea is now to write unit tests for all the different and jarek's stuff of course there's also integration testing and so we can argue about whether or not we want a unit that's the store or you want to do some more integration testing I don't want to go into details in into that today the idea of today is to show you how you can unit test every aspect separately and I feel it's still up to to you whether or not you want to unit test everything separately or you want to go further more integration testing testing different parts of njx at the same time so first things first we show I showed you how the application looked like from a user perspective so let's dive into the code and see what we have before we write some tests I'm gonna make sure my font is big enough so our application consists of only a few components in this case we have the all shows component and we have the favorite shows component both components are responsible for rendering the corresponding page and as you can see sorry the all shows component is using the store to retrieve this shows all the shows and is dispatching the corresponding actions to fail it unfavorite and remove the shop just calling stores of dispatch with the appropriate actions favorite show is doing the exact same thing it's using also an observer to retrieve the favorite shows in this case from the store and dispatching three different actions we could argue that this is the exact same code so we could probably avoid duplicating it but for the sake of this demo I have separated two code which will be more clear why I did that when we dive into the testing there's also a reusable component for the visualization of the shows but that's not relevant for for ngrick that's entirely decoupled from venture X then the most important part is everything that's NGO X so we have actions file and the actions file is going to represent all the actions that we will be dispatching through our application so first of all we want to know whenever the application is loaded because we want to retrieve some initial data whenever the application is loaded whenever we achieve that data we're going to dispatch to get all success action and again our field potentially if something went wrong sorry we also have the all shows actions which is an object that contains three properties sorry three properties one one that contains the favorite show clicked action the unfavorite show click action and the remove show click action those are of course the ones that we were dispatching from our component whenever the user clicks the corresponding button these are the actions fault if all shows and now we have the same actions for the favorite shows so we have the same actions but the actions define where they are dispatched from so in this case we know that the show is favorited from the favorite shows page and here we know it was favorited from the all show space and then because clicking a button or favorite thing on favorite in the show is actually an HTTP call and we also have the 6 the corresponding success actions and normally we also have the corresponding failed actions but in this demo we are not really handling errors which you probably would or should do in your application so other than reactions we have producer the juicer is responsible for keeping track of our state we have four actions that we are handling so get all success basically sets all the shows just at the payload contains a shows array and going to update a store with all the shows it's going to override everything it's not going to concatenate anything it's just going to take one of your trees and puts it in the store favorite show success will basically update a show based on the show ID and said that his favorite property to true well unfavorite show says that is failure property to false and a move show success will just filter the array and ensure we return a new array that is that doesn't contain the show that we have removed so this is a reducer and of course we have a selector so njx as the ability to provide to create selectors which allow you to actually select subsets of your store so our store contains all of the shows as a single array but we want to be able to at some point but retrieve only the favorite shows for that we can create a selector that is basically using all the shows and it's only retrieving those that are that have is favorite set to true and this is using the create selector so we have actions reducers and selectors and last but not least we have the effects effects are the most complex part of the demo mode from the code itself as for the unit tests I think it's very interesting how it in unit test effects I think it's very easy and once you understand how you can test it depending on the complexity of your effect itself of course so as I said whenever the application loads we want to retrieve all the shows through the service map into a get all success action which will be handled by the reducer and update to store as you can see I'm not handing any error case in this reducer in this effect so again which you probably should then we have favorite show which is also an effect us in this case listening to two two actions the favorite show clicked for the all shows and the favorite subject for the favorite shows whenever one of those actions is dispatched we are calling the fail it show on a show service and map it to a favorite show success action in this case we are handling the errors well you can call it's not really handling but we are ensuring the observable doesn't break but you probably want to do more and just return me off No unfavorite show is doing the exact same thing but it's calling the unfavorite show on the show service and mapping you to an unfavorite shows success action Eddie move show is calling the remove show on the show service I'm mapping it to remove show success this is the effect so the last part that we have is a show service which theoretically is a service that goes that doesn't HTTP call in this case it is just using internal erase and stuff like that to to make it easier for this develop but again this is not something we will be testing testing a service is not related to 10 gr X so we will focus on everything for ng x the first thing I want to test is the reducer very juicer let me close the rest reduce it is actually just a function it's a pure function that retrieves two arguments if you can see here a function reducer is a function that retrieves the state and an action and it's going to return the updated state that's basically what reducer does simple function they give it a state and action and it returns the new state so the first thing I've written the boilerplate for all my tests already so first thing I want to test is that my reducer doesn't handle an action that it doesn't know that's the first thing you want to do so for that I'm going to create an action that we shouldn't be handling let's call it an action twit pipe of a node this is something that isn't registered to a reducer and I reduce it should not be anything with that esta you reduce it it's just the same as testing a simple function so what a juicer it's a function that we should call it a corresponding arguments which is as I set a state and the action we don't have the state yet so we need to create the state there are two ways that we can create a state we can either for every tests created state manually but we can retrieve the state the initial state I'm sorry from our reducer the answer users provide their initial state in this case it's an empty array but every reduce it can define its own initial state we can use that if we want to however despised the test to the initial state here so if we would change the initial state which is using an application that might break our test so you can decide to do that or to not do that that's that's up to you and so now we can call it function with the initial state and the action and it returns it returns the new state then what we want to expect is that a state it's the same as the initial state are using to be we are both actually checking that the value is autistic well you're actually just checking at the reference is to say use the same we've it used to echo to be equal only checks the properties in this case you want to ensure that nothing has changed so also the reference shouldn't have been changed so we can do to be we can save it and our best should run again and this should succeed we can have we have 25 success tests but of course every other test is successful because I don't have any expectations but this test is now running successfully so what do we do to test a reducer we build up the state so the state that is being sent to the reducer and the action that reducer should or should not handle and then we basically do an expectation on the returned value and see if the modifications to the state have been happened in this case we don't expect any modifications so we expire that that's the case so this is interesting but it gets more interesting as soon as we start testing actual state updates so the next thing is we want to test if we if it updates the state whenever and get all success hacks action is dispatched so in this case we need this case I'm sorry need to call the register again which is going to be the exact same code as you this is going to be identical all the time so you're going to call the juicer with our initial state and we are actually in this case our action is to get all success action right so we want to verify that the reduce that handles the get all success action to get all success action expects the shows for a so a new state so we have the initial state which is the state before sending the action and we have the new state which is actually the payload for our action so in this case the new state should be an array of shows so I just pass it create a new state object or array that contains one show and I'm sending that action to my reducer and then basically I want to expect that the state it's equal to the new state right so you want to ensure that the state that we retrieve from our reducer is the same as the values or the array that we send it and then probably you also want to guarantee that it's immutable so it shouldn't be the same reference right so you want the state to have the same values what you want to ensure that it's wrapped in a new object so that it's always whenever we send something as part of an action to the store at the store ensure that it's updating the state immutable so there was a valid point about about the fact that the properties the reference can could be the same but the properties can be mutated true sure so of course you can decide whatever expectations that you do on your test so in this case we could add it to equal so you want to ensure it is the same reference but it also has the same properties you can start comparing properties by properties you can you can create your expectations the way you want of course there is there are for every test there will be multiple expectations that you can do but it's a valid point that in this case we could have the same reference but we could be updating the stock this day which is also something that we want to be careful from because you don't want to do mutable changes in your reducer so it's a valid comment from Georgie that you wanna ensure that you also do not chase any properties in this case but this is of course the case for every test that we are going to write for the reducer you want to ensure that it only changed the properties that you expect it to change which is not something we are going to focus on for the other test we are going to focus on everything we expect to have changed but of course you might want to have all the tests that ensure that it doesn't change anything you didn't expect that it changed okay so sorry back to this test so the get all success action should be dispatched with a new state it should pass that action to the reducer together with the initial state that returns a new state and then we can get check that it's equal but not the same so the properties are the same but it's not the same reference this is actually guaranteeing that in this case we are creating a new array the case we will do this this would actually break our tests but in this case it's not an it's not a new instance all right we have one field so the next thing we want to do is we want to ensure that it handles the favorite shows success action which is going to be compatible as well right so you want to have we want to call the reducer in this case you want to call it with a favorite show success action so we create our action which is the one that we are going to dispatch to the store so whatever if show has been successfully favorited we create a future success action positive appropriate payload which in this case is show ID 1 and we sent that action to our user a reducer also in its initial state which in this case I'm now creating my initial state myself I'm not using the initial state from the from the juicer anymore because I really wanna I really want to take control of my initial state so that I know which state I have before sending my actions which is actually in my opinion a better idea because it keeps your tests decoupled from your initial state in your inducer so whenever we have this state which is which has an idea of one and this favorite false and we sent a favorite show success for surely one to the store we expect that a state state look as one item whose favorite property is going to be true then we know that whenever a favorite shows the expense action is being dispatched to the store the store the the movie or the TV show in store its favorite this favorite property is updated to true of course if we want we can add oh if we want we can add another show of ID to which is fail it false and guarantee that in this case the second show favorite property is untouched it's still false all right so whenever an favorite show success actually a specific show ID that matches the show in the store is sent to the reducer we know it's handled properly properly however we want to do the same thing with an show ID that doesn't exist so in this case we have an initial state with an ID 1 and we have a favorite show success with a show idea of 2 this means that this show ID doesn't exist in our store so in that case we want to guarantee that it doesn't touch our state right this isn't the most useful test I would argue but these tests that whenever it doesn't match find anything in the store that it doesn't really touch the storm well it does touch the storm in this case it will create a new array but it will not change any property right so it so in this case the state we can do not to be the initial state right then we guarantee that it's a new reference which is or isn't something you might want in this case right because whenever it didn't find anything why would we know once another state so we in this case we could decide to remove that and update our reducers to ensure that it doesn't touch the store in case it doesn't find an ID it will make you reduce a little bit more complex but writing tests this way also finds books or special education your reducer that you might want to change or handle different thing but as you can see there's always the same pattern in testing the juicers you create an initial state you create an action you call it a juicer it returns a new state and then you do expectations whichever you want right testing and your ex isn't really telling you what you should expect it's more about the stuff that we are doing before up front that is about how we can test all this stuff so unfavored show success is going to be the exact same thing I'm not going to go over all the tests but in this case for contrail ensure success when it should update the state in an immutable way so whenever we send an unfavorite show success action to the reducer or initial state will ensure or reduce it will ensure that the initial state is updated and that the disfavored property is set to false and this will be same for all other tests I'm going to copy all of them in here that we have all of them working so it should not update the state when show ID should not exist so when unfavorite show success is sent is this best way to show you that we don't know the store is faded property is still through then with remove show success we have the same things that we wanna test so whenever we dispatch the remove show success we expect that it is removed so in this case we have an array of one show we dispatch the shows remove show success which show anyone in this case we expect that now the array is an empty array and whenever it doesn't find the ID we expect that the array is still an array of one item but this is actually the pattern that you can follow to test your reduces of course some of the users are more complex and involve more complex testing but again that's more part of how you can test your code rather than how we can test and directs itself so testing reducers is actually as actual is not that hard or not that special to njx itself it's more like testing a function the next thing we want to test this off part of as part of njx is our selectors or our our selectors so in this case we have one selector which is basically taking the shows in our store and only retrieving the shows that are marked as favorites so we want to write a test that tests that and that's interesting because let's keep let's get my selector so my selector is select favorite shows and that actually has a projector methods projector method is part of the selector in njx it actually is a method that can be used to project my selector on some kind of state in this case my state is an array of shows so let's say we have an array of shows in this case we have an array of two shows one with a new one that's fair and one we like the idea - that's not favorite this is just a simple array of shows and we can send that or pass that to the projector method for the selector has a projector method that bakes in the state this is new this needs to be the same type of your state but in my case the state that the selector works well uses is the value returned from the Select shows we're going to test the Select favorite show selector which uses the Select shows which returns an array of shows right so initial state has to be an array of shows and this returns the results but this is actually there's going to be the result whenever our store should contain this list of shows and now we can expect that our result is actually at a length of 1 and that our first or our only item you know our array as an ID of 1 so this works this works again so this is actually how you can write tests for selectors a selector is always something that works around a given set of given state in this case select shows right this isn't a selector even though I named that select shows that's actually not the best naming all it get all shows because this isn't a selector this is just an arrow function that's retrieving this the shows property from the state which is different from a selector a select event and your X is something that uses create selector and because we use create selector you can see that this has the project methods that zoom on we are using so let's rename this to select shows again so this is the Selective that we have and that we are using throughout our application and this is how you can test select us selectors are probably not the most fancy thing to test in your application but it's actually pretty cool if you start using selectors extensively that you can guarantee that it returns or it selects just a portion of the state that you expect it to select which you can do it with a few simple tests that use the projector but now the the most important most complex and maybe also the most interesting part of testing and grx is testing effects all right we have a few effects that are actually going to listen to an action stream this is the effect always starts from an action stream so we listen to the action of stream I mean ever an action of a specific type that you are interested in is dispatched then we do the effect does its thing right in this case we are going to use exhaust map am I going to get all the shows from service which will be the back end and that that will get all success action again an effect the result of an effect is always an action and the action will then again bit be dispatched you could dispatch an action from an effect or it were an action from an effect and handle that in another effect you could do that but you have to be careful as well as was mentioned in the other talk about ng rx from my colleague Rob Rob hotel I think he talked about being careful with I don't know how we named it but the fact that you can have in effect trigger an effect triggered another the effects you could not yet another effect and eventually you will lose track of whatever is happening but in this case get all success will be dispatched and in this case handled by the store so let's write a test a test for this effect and but before we do that I created some boilerplate and I want to go over the boilerplate that we need in order to test the effects so up until now I didn't use angular's test pet so angular has a test better if you use to configure testing module for effects I will be using that because I need to provide some some things to the providers of our module and that makes testing easier we can test this without tests but I feel like using testbed for this is a lot easier so first of all our store will need an initial State again we could retrieve the initial state from our reducer and use that here but again I've created something that isolates the initial State in my test from the initial state in my actual application then I want a show service mock so I have a show so Elvis that is being used by the effect so you can see I injected show service and it's used throughout every effect so I need a mock version of all my methods get all favorite show and field show when you move shop this is because I don't want any of the actual implementation to be executed now then I keep track of a few things that I will need layer of course as we are testing our effect which is called shows effects I want to keep track of an instance of my effects that I'm testing then I want to keep track of actions which is of type observable any which actually is going to represent the action stream which is going to be the stream that you are injecting in our effect and is the one that is actually used as the trigger for every single effect we are keeping track of an instance of our action stream to ensure that we can manipulate that stream because as that is the trigger for every effect it might make sense that we need that action stream to manipulate an action stream in order to be able to test some things right we want to send something through that action stream and verify what has happened and then I want to keep track of the store which is a type mock store we are not using of we are not using the store type you are using the mock store type which is a little variant of the store allowing us to do a little bit more than what we can do with store but more on that later and we are going to use the test schedule but I will explain that later that's part of our XJS testing which I will explain a not deeply I touch it slightly a little bit later but I will need an instance of a test schedule so first I created test config I go figure testing module and I specify few providers so my shows effects are not much version this is my actual class then I ensure that I mock my store so Angelics Angelics has a provide mock store function that we can call without initial state so it is ensure that ng rx is set up in a market state right this doesn't this doesn't register a full-blown store this is just whatever we need for mocking the store and I want to use provide mock actions which is also from ng or X let me see which is from Angelics effects provide mock access is from effects which actually allows us to register a callback so this is a callback so this is a function that returns the observable that we created here right so this allows us to manipulate the action still we will use here right so ng rx is going to use this callback and call it then use the actions that we that is returned from that arrow function as a source for its action stream I hope you get clear later and I lost but at least we want to register our shorts our shows service mock then this is a nice way to retrieve the instance of our registered services so we can do effects equals test battle to inject shows effects which retrieves the instance the shows effects instance that is registered with our that's that module same with store we want to keep track of the instance of the mock store and then something interesting the mock store is a spec as I said is a special type of enginex store which has a few extra methods such as set state so the mock store is actually the mock store allows us to set the state instead of dispatching actions right if you would just register the store you can dispatch actions until the store is in a way that you expect it and then write some tests but instead we can just use our box store and call store dot set state and set the store in a state that you want we can do this in a before each or we can do this in a on a per test basis right we can for every test we can update override state and ensure that the state is in this that the store state is in a state that we expect but that's a weird sentence but yeah I guess I hope you get it so this ensures that our store is set to an empty array which is actually useless sorry that's also my initial state so there's no need for me to set the state to the same thing as the initial state because that's already happen by calling provide mock store but sure and now we have test schedule here's a link as much asked in that comment thread yes you can get access to the demo to the to the code after this session follow me on Twitter or with my Twitter if you don't want to follow me and and I will tweet out the link to my to the code source code so the test scheduler there's a link to all exist documentation that explains everything about the test schedule but that's basically something we can use to execute our effects in a synchronous manner we need to do this so we need to assign a test scheduler to a new test scheduler and expect to actual to be x2 equal expected I'm not an expert in whatever is happening here the documentation that we have here which I can show you just so that you know that I am NOT making this up you will see that the documentation for a yes is talking about it that's scheduler and the first thing that you need to do is write something that does the assertion for you to expect that something is equal you can do more right you can do a deep equal you can do it equal you have fo totally control or whether or not of do this to define how something is considered to equal or not equal but this is an interesting base if you want to dig into what the scheduler is about so first test should be created if you can ignore that but the first thing you want to write is get all shows should handle the uploaded event and return and get all success action so that means that whenever a product is being emitted as part of the access stream we expect that this effect returns to get all success action that's what we want to test so to do that it's gonna be a little bit more complex but we start with defining the triggers of our defect so the first thing is we want to have an action that is going to be dispatched so we want to have the app loaded action so it's going to be the trigger you want to have the outcome of our effects right so the outcome is going to be a get all success actually it's gonna contain a shows array type so we need to define which so it's array that is going to be the actual let's call it the response of arts HTTP call or if the Pico is going to return an array of shows so let me let me steal some shirts like this now you have an array of shows so you have an action which is the app loaded action that does not have any arguments and we have the outcome which is of type get fall success which has an array of one show all right the next thing we do is now we need to use it best scheduler the best schedule has a run function and the run function is called with an object that has a few proper this right so we have a run we have a hot cold expect them and expect all jumbled again not an expert in s scheduler but basically by using hot and coffee can create hot and cold observables the difference between a hot and a cold observable sorry if I'm wrong here but I think observable basically means that if you didn't subscribe in time you will miss it and a cold basically means whenever you subscribe you get the entire emission of items again I always explain it as if you're watching a movie if you watch a movie at home sorry if you go to the theater and you run late you miss the beginning of the movie right the movie is not going to wait for you so that's a hot observable but if you're watching a movie with a friend and you're gonna be later you call your friend that you're gonna be late the friend can wait and start to show whenever you arrive that's more like a hotter to call them so right so how observable is if you subscribe whenever after an event has been admitted you won't get that event anymore and of course whenever you subscribe after the event has been emitted we will still get that or all omits of that observable where again I'm not an expert in hot versus cold ovals and then we can use expect observable to do the expectations all right so now the first thing you want to do is you want to create our action stream our action stream is going to be a hop observable and now we need to use some marbles the egg diagrams this is gonna be a little bit tricky I'm going to explain that but a marble diagram is actually something we write some comments is actually something that so one observable it's something that emits items over time right and marble diagram is actually something that visualizes that emission over time so let's say every tick every - that I have here is 10 milli now we can decide that let's say we have one two three four five six dashes that means six milliseconds or 60 milliseconds and we can define it after 10 milliseconds it has to emit a and after another 10 milliseconds it has to meet B this is very cryptic but this allows us to control the observable that's emitting items over time right but then you can ask yourself but what does a mean there's a second part minute that we can use to define what the values are so we can we can call this B and then we need to ensure that this is called B as well so that click this object is used to map the values we have here to the actual action that we have defined here so if you would look again basically we are creating an observable here that's emitting an action the uploaded action on the second tick right so this is this is actually implementing something asynchronously we could we could remove this - in the beginning and then we would just happen as a stream that immediately emits the action but for for for the purpose of this demo let's add a dash and an extra frame is what it's being called in in marble testing so now we actually have our action stream which is our stream that's being used here right the action stream and we know that this exit stream will be an observable that will eventually not instantly but eventually emit the app loaded action of course our effect is using a service and it's using the value returned from that service which is called shows choosing the value returned from that service and passes that to the get all success that means that the shows arrayed we are here expecting in our get all success action we need to have that being retrieved returned from our get all methods to do that we can do the following so we can play it create response which is also going to be observable this case is going to be a called observable that is go we're going to return our outcome outcome of shows all right so this this is now this this is using the cult function that we get from the test schedule this is going to create an observable again two ticks tens ten milliseconds another ten milliseconds and after 10 milliseconds is going to emit the shows array that we have here and that we can basically set up our show service to ensure that our get all method returns the response so now our show service don't get all its configured to return an observable that is emitting the shows in an asynchronous manner again right and of course it will also complete by using marble diagrams when we use a pipe we basically tell the observable it completes and then the last thing we have to do it we have to expect so we can use expect observable which is a different expecting what we have we have no other paths we can use expect observables instead of expect and then we use we need to use part effect next case we have pests in the pet or shows effect and you want it to be equal to another marble diagram right so now you'll need to figure out what marble diagram or effect is going to be so we start from an action stream that is emitting a value or action uploaded after two ticks after two ticks it will map that value to another observable that emits a value after two ticks again right so this means that actually our value V which would be our outcome will be emitted after three ticks right because actually you need to see the observables if you see them below each other it's how should see them whenever a emits the other observable is triggered but the other observable does not instantly return something it also starts with an empty ticket and then it returns B so that means that if you had paid the combination you would only get B after the third pick not before not a second 31 Wildmutt will be against is a little bit tricky but it's very important if you want to test your observables your effects without doing some kind of subscriptions or anything else so now we know that after critics it will emit V and V will be our outcome where outcome is our action of type get all success right so if you would save our code now we would still have 25 successful tests just to verify if we would add another big what rest should feel so it does fail so now we know that our best works by using best scheduler everything everything is run its synchronously we don't have to worry about a sync on TV don't have to call any anything like tick or anything this is how we this is actually the general pattern how we use when you write an effect right so I will write a test for an effect so we start with the action that we want to dispatch as part of the access to dream we define the outcome which is a return action of our stream and then we run the test scheduler which creates the action stream and funny this is in all my tests that I have for this session this line is going to be identical because we define an action and our access stream is always going to emit that action in my case always on the second tick you can decide maybe some effects require another tick not sure why but maybe that that's going to be the case in your in your application but in in this demo this would be identical we always need to do need to create a response the response will not always be the same we're not always calling get all sometimes we'll go in favorite show on favorite show or whatever now we always need to do an expectation so let's go over to the second test and see what we need for that I'm not going to write it all by hand but I'll go over it again so we start with creating the action that triggers our effects so let me open the favorite show effect which in this case listens to new actions to dream and whenever favorite show clicked is emitted it's going to kick off so in this case we register a favorite show clicked with a specific show ID in this case the surety is equal to one and then the outcome is the favorite show success action if you would open our effect we would see that our effect filters a favorite show success action whenever everything happens successfully then again we use our test scheduler we define our action stream as I said identical to what we had before we define our response which is identical to what we had before however in this case I don't care about the response of our service our service favorite shows returns something here I don't I don't care what it returns as long as it's successful I already know the show ID and that's all I need to update my store so that's why in this case I use able I could use know whatever it wasn't really the most ideal value I guess so now we have the exact same kind of response but in this case we use show service dot favorite show and mock that to return a response and then again expect our favorite show effect to be equal to - - B where V is our outcome and you will see that again this is successful so would it be the same to write hot a and Colby and expect - be so you can rub this you can drop this and then you can lock this that's what we're asking and that should also work that's interesting should that also work there is no because there is no empty dick I guess there is no asynchrony right yeah because if we would write that out you would have a when you have instant B so yeah because previously if we write that if a that means that here we have Big B and that means that now we have cryptic be right a emits and that picks up the other observe but the other observable is an empty tick B which results in two ticks but if we have a and B without an empty tick the result is instantly B and not that should be yeah this is how we can cast favorite show for fun G let's also do fun favorite show but really this is going to be exactly the same again we have our show the idea of one we have our actions dot unfavorite show clicked which is again the trigger for our own favorite show effect and this is our action then we have our outcome which is unfavorite show success action with our same show ID we have our test scheduler or actions to beam or response trim and we setup our show service dot unfavorite shows mock and have it return response and then expect the others effect now and favorite show - B - B where B is outcome and now this would also work so this is how you can write defects there's still one more to go but I would also write like to end with testing or components instead of only effects but this is actually the pattern to test effects which is in a lot of applications that is this this code is really identical so let's move over to the favorite shows components well the test file of course so the favorite show has a few things that we want to test I'm not going to try and rush this but I am gonna try and finish it so the favorite show is doing two things the component it's either dispatching the corresponding action to the store and it's using the selector to update the UI so I've created some boilerplate to set up my tests this is normal boil play to test a component you get a fixture components we want to use the mock store again I have some initial state that I want to use to drop my tests then I have my before each to configure my test bed in this case I'm using angular materials so I need some material modules I'm using a provide mock store because I'm not using effects I don't know need to use provide more actual ease in this case and I need my decorations for the test the components that I'm testing which is the fav favorite shows components and the shows component the shows component is the dump component that I mentioned that is not really part of whatever we are doing with an TRX then I need to keep track of all my instances that I want to track and I call fixes or tech tech changes then I'm also calling spying on the stored of dispatch and called fake because I don't care what's happening whenever we call dispatch I just want to ensure that it dispatches favorite show clicked whenever we call favorite show on our components and actually this is all you have to do is call this so we call the favorite show on our components so we provide it with to show ID of one and you can call a famous show with show ID 1 and now we know that it should call our favorite shows X or thought that this pack should have been called with the favorite show click action this is a simple test this is just ensuring that whenever we call the component dot favorite show that the action is being dispatched you can take this not one step further and actually click the button using angular testing and expect that the service has been called I don't have that in my demo but that is actually just the same as you would test any other click event in in angular and then expect that to store this patch has been caught with the correct value so the unfavorite and remove show are identical and then I want to add one more thing to my to my demo that I think it's very interesting to know now this whenever your component in this case favorite shows is using a selector we have something cool in NGO X that allows us to modify that selectively because the selector is actually a projector a subset of your store so in order to test that selector you could set up the entire store to satisfy that selector but if you have the very very complex selectors that combines a lot of stuff from your store you will have a lot of code to set up your store instead there is something in and directs that allows us to override our selector for our tests right you don't want to test our selection in this case we are already we have already validated in our other tests in our selected test that the selector selects the correct value from our store now we want to test that our component renders the correct stuff based on our selector we don't care about whether or not the selected works but this is the point where you could argue well maybe we do care and we don't want to unit test everything but we're gonna write an integration test instead the valid points you can go with that but I do want to show you that you can also unit test and mock your selectors by calling store dot override selector so store is in this case the instance of mock store all right selector the first argument is your selector so if you would click it you will see this takes me to my selector the second argument is the value for that selector and they can call feature dot detect changes then we want to test that it renders all my favorite shows it is not pretty relevant but if you would open show that component with HTML you would see that every show is a matte card so if you will have multiple shows we have multiple met card components so in order to verify that a number of shows are rendered by basically using fixtures of the web element of query all and I create my elements by CSS by selecting the total net card and actually just counting how many math cards are rendered which in this case is 1 so this works and now we know that whenever are selected as a certain value or UI reflects those values well we should also test the name and description which we can now do if we want to but other than that there is something more to testing selectors that is that you can set selected so the store would override selector it returns a mock selector and a mock selector is of type honestly I have no idea what type it is memorized selected apparently that has a method set result and set result is actually something that you can use to update the result of that selector for a specific test so now you can say that that same selected in the first test it has a length of 1 but in this case we are updating that selector to return an array of two items then we call store dot a refresh state and fixer dot detect changes store thought refresh state is a method on mock store again not on the actual storable in a mock store and then we can just guarantee or query the debug element by met cards again an expected the length is now too if you can save this you would see that you now have two math cards and that all my tests are working and this is how you can mock selectors and how you can put unit test components that are using selectors and/or using stored or dispatched without a lot of complexity of the store if you would do a really integration test you want to set up the entire store it can get really complex I've also written project where where we setup a lot of dispatches to the store and before each is to ensure that the store is in a specific state while actually if you use selectors that's not necessary this is basically what I wanted to talk about nginx as part of this demo as I've mentioned before the source code will be available on get up and I will tweet that after my demo go take an out or something but I'll tweet a link so you can get the source code player applet and please feel free to ask any questions ping me on Twitter about how we can achieve anything or if you have any questions and keep in mind if you find this training helpful and you would like to learn more please let us know we would love to teach you more because this stuff laps is also offering virtual corporate trainings so on that note I would like to thank all of you for attending and have a great rest of the day
Info
Channel: This Dot Media
Views: 6,168
Rating: undefined out of 5
Keywords: JavaScript, Angular, Vue, React, RxJS, React Native, Flutter, Lighthouse, Cypress, Bazel, NgRx, Node, Ember, HTML, CSS, Tailwind, TailwindCSS, web developer, javascript tutorial, programming, architect, This Dot Media, Tracy Lee, Google, AWS, Azure, Microsoft, software engineer, developer, Laravel, NextJS, nuxtjs, women in tech, 100 Days Of Code, VueX, react hooks, GraphQL, react js essentials, angular essentials, vue js essentials, API, modern web, podcast
Id: NOT-nJLDnyg
Channel Id: undefined
Length: 59min 45sec (3585 seconds)
Published: Wed Apr 29 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.