Adding AJAX Update0:00
Now, I'm still working with the source code from the last episode, where we test-drove this question component. But now if I scroll down to the update method, you'll see, just as a quick recap, you click the edit button, you type in an updated question, you click the update button, and then that hits this method. Okay, but right now, all we're really doing is updating the fields, and then turning off editing mode. In real life, you'd probably submit an AJAX request to your server, right? So let's see what that might look like. So it sounds like maybe if you're using Axios, yeah, maybe you have a POST request to question
So let's see what that might look like. So it sounds like maybe if you're using Axios, yeah, maybe you have a POST request to question/, and then some kind of ID, and then you would send through your form data. And then maybe when you're done, you would receive a response, at which point, I don't know, maybe you update a status, you show a flash message, something like that. Okay? So let's comment that out and figure out how we would go about testing this. And you have a couple options. Now some people would say, just set up a server, go ahead and hit the endpoint, and that gives you full assurance.
Choosing a Testing Strategy0:57
Now some people would say, just set up a server, go ahead and hit the endpoint, and that gives you full assurance. For testing a view component, though, that feels a little off to me. I don't want to test Axios, I'm not testing my server, I'm not testing the request there, I'm just testing the UI here. Now another option would be to use a test double of sorts. So I'll give you a handful of choices. HTTPIN, this is actually pretty cool. So think of this as like a dynamic API that you can use when testing or working locally. So for example, if you make a POST request to http://httpin.org, you send through some data,
Installing Axios and Moxios1:56
library called Monxios that will help you with this. So for example, if we take a look right around here. So yes, about this request. So if I make an Axios call to say /hello, we want to return this response text and a status of 200. So now when you're testing your code and it makes that call, we're no longer going to hit the endpoint, we're instead going to return this stub. So let's give that a shot. npm install both Axios and Monxios. Next I'm going to switch over to my code project, and let's see.
We type in a new title and a new body. We click on the update button, and that should now submit an AJAX request to the server to persist it. But I'm not really interested in testing the server for this test. I'll probably have a php feature test or for whatever language you use that will assert the endpoint forward. So here I'm only focused on the front end. Why don't we do this? We're going to import axios. And you'll see now there is a little bit of setup if we scroll up.
Setting Up Moxios Hooks3:11
We're going to import Monxios. And you'll see now there is a little bit of setup if we scroll up. So we have to say before each Monxios install, and you can pass in a custom Axios instance if we need to. So maybe window.axios or something like that. And then after each we need to uninstall it. Okay. Monxios.install. And then we can say after each Monxios.uninstall. Okay.
And then we can say after each Monxios.uninstall. Okay. Now we can scroll down and we can say, well, let's see, Monxios. And yeah, you'll see we have some examples here. So you can fetch the most recent request dynamically and figure out what that is and then respond with your data. Or you can stub an existing request. So in this case, you pay the price of hard coding the test to the endpoint that your main production code is going to hit. But the benefit is it's very readable.
Stubbing the Request4:02
main production code is going to hit. But the benefit is it's very readable. You can just say, okay, this endpoint corresponds to this response data. And that way I never actually hit my server. All right. Let's give that a shot. So we'll hit a endpoint, maybe something like question/1, or we can even make this a regular expression to make it more dynamic. And if we hit that endpoint, I'm going to return a status of 200 for updating the resource. And then we'll say two things.
And if we hit that endpoint, I'm going to return a status of 200 for updating the resource. And then we'll say two things. You could do response text, and that would be for any string you want to return. Or if you intend to return JSON, you could use response as an object here. So maybe here it's just going to return the existing data, or we may not even care. It just depends on the test we're writing. So let's just imagine we're going to hit this endpoint, and then the response is just going to be the updated record that has been saved. Okay. So now we're stubbing this request.
Okay. So now we're stubbing this request. Let's come back here, and we'll say Axios, and we do need to import that. There we go. And then we'll say right here, console.log, done. Okay. So let's give this a run, npm test. Okay. And we do see done here. However, let's take a look at the response data.
And we do see done here. However, let's take a look at the response data. One more time. Okay. So here's what we got back, and specifically notice the data here. So we were able to stub that out and return our custom data without actually making a real AJAX request. So now what you can do is say something like, well, I want the data, and then I can say data.title, run it again, and we get change title. Okay.
data.title, run it again, and we get changeTitle. Okay. So the two things to keep in mind here, the two trade-offs you're making, one, by pulling in Moxios, you're saying my production code uses Axios. So if you ever switch to, for example, jQuery.ajax, that would be an issue, and you would need to go and update your test to accommodate for that. So if that's a concern for you, yeah, you might want to use something like sign-in or test double, which is a more agnostic approach, a more generic approach. So anyways, let's finish the test by saying, all right, once I click the update button, yes, I want to see the updated title on the body, but maybe I also want to see some kind
Testing Feedback After Update6:11
So anyways, let's finish the test by saying, all right, once I click the update button, yes, I want to see the updated title on the body, but maybe I also want to see some kind of feedback message, like yourQuestion has been updated. But now if we give this a run, it's of course going to fail because it won't see that there. Okay. So let's grab all of this. We'll come back, and then maybe right down here, I'll paste it in. So right now, of course, the test is going to pass, but we're displaying that feedback message no matter what, which is not what we want. So maybe we could say, if we have feedback, only then should you display this paragraph.
message no matter what, which is not what we want. So maybe we could say, if we have feedback, only then should you display this <p> tag. And then later if we need to, we could even make feedback a property, and that way we can dynamically change it. So for now, we can start with this, and then we could say, feedback is false. We don't have any feedback at the moment. So we give it another run. It'll fail because it doesn't see that. All right.
It'll fail because it doesn't see that. All right. We come down, and then maybe here we'll say, okay, well, once we've hit the server to persist it, the server will do what it needs to do from that point forward. Then I could say, this.feedback equals true. So let's see. Yeah, it's still failing. So what's the issue here? We know that we caught this AJAX request, and now when it's done, we're setting feedback to true.
We know that we caught this AJAX request, and now when it's done, we're setting feedback to true. Once feedback is set to true, we display this message, but the test is still failing. And that's because we still have to wait for the request to complete. So this is where you'll see moxios.wait come into play. Wait until we're finished and all set to go, and then we can perform our assertions. Something like this. Let's come back, and we'll say, okay, moxios.wait, and then I'm going to assert that I see this. But now I think you'll see something new. So if we run it, will it pass?
So maybe you don't know if it's one or what the ID is. You could always use a regular expression. So you could say, well, I know the endpoint is questions, so maybe I want questions/ and then anything. I don't care. So now let's do another run. We should be at green, I think, and we are. So yeah, in this case, we're just providing a regular expression. I want questions, a forward slash, and then a period is any character, and a plus is one or more of the preceding character.
I want questions, a forward slash, and then a period is any character, and a plus is one or more of the preceding character. So basically, after questions, just look for anything. Anything will match. Or I could say any digit will match, and that will still return green. All right, so hopefully that should help if you're testing against Axios. You can say moxios.stubRequest. You provide your custom response data, and then you can wait for everything to complete and perform your assertions.
