 So this is a lot lower resolution than anticipated, but it will make this work. So feel free to follow along the address up here. I'm just going to go through some tips on doing, like working around remote APIs while doing testing on your code, because the simplest thing to do without any magic is to just set up a staging server and put some values in there and have your code tied to it, but nobody really wants to do that. And we're rubious and we can do anything. So this is a better way. So I have five escalating and hubris tips on ways to address that. So I'm just going to walk through some code. After following along, it's in the aspect folder. So the first one is just stub away the client. And this is obviously not amazing, but it's the simplest. And if you're working around a well-tested client, then that might be good enough. Maybe you don't actually care that much about the remote API. Maybe you're testing a certain thing. It doesn't depend on it. It's quick. It's obvious. You probably already know about this, but it's a good starting point. So what I'm testing here is it's like a robot depot where you have like a robot arena and a tourney. It doesn't really matter. But the idea is that you're setting up some robots and you're telling them to fight and there's a winner and blah, blah, blah. So this will have this little tourney class and basically pass into robots. And then you tell it to fight. And so the simplest thing, if you don't really care about the APIs, they just stub it out and say, I expect it to enter twice and then receive fight. And then maybe you'll even go as far as to take some of the internal models from the robot arena, which is wrapped around. But anyways, I'm not going to spend too much time on this one because it's not very interesting. But instead, if you want to actually be able to kind of do a more full integration kind of thing, because the problem with that is that you're not actually going into the client. You're just kind of stopping at the client. You can actually use WebMock to kind of catch the calls into Net HTTP and then just return some JSON or whatever. Obviously, the downside is you have to know what JSON is supposed to return. And presumably it's not going to be making a bunch of different requests because you have to write code for each one. But in this case, we're writing tests for the actual robot arena cloud. That's weird. OK. Actual robot arena class. And that's kind of like a client for the robot default server. So what this does is you kind of saw its usage before. You kind of enter some robots, blah, blah, fight. The point is that when you enter the robot, you kind of post it to the server. And then you get back a rating. Anyway, so what we're doing here is we're going to be stubbing out some requests. We don't really care about the gets because that's just checking if the robot already exists. So we're just saying 404. And then for the posts, the first time we're going to do the first calls when we enter sissy. And sissy is not very good. It's just a plastic medium robot. And we'll kind of just return that JSON along with adding a grade because we know that's what it's supposed to do. And then when it does your robot, then it's going to return your robot with a higher grade because our robot's the best. And then when they fight, it's just going to check that the name is actually the one that it's supposed to be. So again, this is kind of a little hard coded, not really testing that much behaviorist. But it's kind of still going all the way up to an HTTP, so everything in between there is still getting tested. So it depends on what you care about and what is going to take a lot of work. If it's making a lot of different HTTP calls, it's obviously going to be a lot of work to do this right. If it's just making one, then it's probably going to be more through time to stub out that one HTTP request to get a little deeper. But if you are doing a lot of different requests and you don't want to individually stub them, then you can use VCR, which was mentioned by an earlier talk actually. And the cool thing about VCR is that it's super, super easy to use once you get it set up. Like in this case, all you do is just add a little VCR symbol there. And there's some set up code in the spec helper, which you can check out online. But basically then when it runs the first time, it kind of just catches it, allows the HTTP calls to actually go through the server, and then records all the responses. And then after that, it saves them to a cassette file. It's like VCR. It's kind of cute. But after that, when you run it again, it just reuses those cassettes and just replays. So the point is that the first time you do actually have to talk to the server, which is good and bad. But every time after that, it's very fast and very stable, because it's just going to be redoing those same responses. The downside is that if you have to change what it's doing or test new things, then you might have to re-record. And if you're actually changing something about the server state, then that could be difficult. Because in this example, for example, when you add a robot, it actually stores it on the server. So to make it happen the same way each time when you're recording it, I have to do a delete all after thing. So sort of this cleanup. And in some cases, you might have to do this manually or something. You might have to set up some values manually and then record it all at once. And then you're good. But then if you change it at some point, you might have to have a little read me or something horrible like that about how to set everything up and record everything. And if someone else has to come in and do that, it could be a lot of work and really confusing. And they might just throw it all away. But for certain situations, it's really nice, because it does just kind of work. So if you're not going to be changing a lot, or if it's something that's really easy to re-record, it can be a really nice choice. But if you're kind of using API throughout your whole app and there's a lot of different things you're doing, and it'd be like a lot of work to have to re-record every time, another thing you consider is a fake server. And that's where you actually write a server and kind of plug it in in place of the remote server. In this case, I'm using something called Jamrack. You can also use WebMock, actually. But basically what you do is you say, listen for calls to this server. And when you get it, like instead, funnel them into this Sinatra app. So it's kind of weird, because you actually have to write a server to write tests for a server. So it's kind of confusing. But if the behavior that you're depending on is kind of well-defined and not super expansive and easy to kind of fake, then it can be a reasonable approach. I mean, this is the fake server here. And as you see, it's really not very much code. And it's just like a few calls. And it just kind of stores stuff into an array when I add something. And yeah, in this case, it's kind of checking that your robot is way better or your robot's way worse. And the reason why that might be difficult to do with VCR is maybe the remote server has some non-deterministic behavior about how it grades robots or something. That could be really difficult to write a test around. And you use the real server, because you don't know what the real server's going to do. So when you re-record it, it could do something totally different and break all your tests. So you might want to just fake the server and have it do some kind of reasonable, simple approximation of what the reality is and just kind of check the code that surrounds it to make sure that it works as expected. So yeah, that's an option. And this is an option that I kind of like. And if you want to take it even further than that, or you don't want to write the server, you do want to kind of use the server. If you happen to be doing a service-oriented architecture or releasing a public gem that has a client to your API, you can actually extract the server and attach it right to the test itself. So say you're releasing a client to your API, and your service is really simple, and it's not very private or secret. So you just take the scenario that runs your server and make a modular way to kind of have the database and all the service stuff that it has to do, like in this case, the database, which is just an array. But I'm kind of have a little way to set the database to something else. Then you can include that in your client. And then you can have some kind of fancy method that runs Shamrock and attaches it to the URL. So when someone's testing your server, they can just run that command. And then everything from there on will hit the actual server code, but not on the actual server. And so the advantage of this is that it's almost as if it was really talking over the wire to the real server. The only difference is the few things that you change, like the database or whatever. So this is really awesome. When you can do this, it's the coolest thing ever. And I got to do this at my last company. And it was just awesome, because the whole pipeline between the client and the server was super tested. And there are all these full integration tests included in the gem, because you could write tests against the gem, and then attach the server. And then on the server side, you could include that gem, and in the tests, you could test the server. And then attach the client to the server when you do the test to test the server. And then on the client side, you can attach the server to the client. And then in all your application code that depends on the client, you can have a full integration with the server. And none of it's using the wire. You don't have to do any recording. Really cool. So yeah, that's pretty much everything. And yeah, if you want to check out these tips at URL, and I did a little write up for, sorry, my mouse is being kind of weird. Linux, yay. Yep, there it is. And I kind of summarized what I was saying. And oh my god, we're hiring. So you should totally join us. Yeah, referral candy is awesome. Join us. We'll fly now. OK. Thank you. Thank you, John.