There are some steps that we can take to make these tests run a little bit faster and also make them more reliable so that they will actually pass or fail based off of whether these functions are working or not. Take a look at Load Abraham Lincoln’s wikipedia page.
That’s taken 230 milliseconds to work because we are actually loading Abraham Lincoln’s Wikipedia page. This test is dependent upon us having a web connection working. It’s also dependent on Wikipedia being up and running. When we run this test, we are actually hitting Abraham Lincoln’s page on Wikipedia. When we test our “loadWiki” function, we require Wikipedia.
The “loadWiki” function is actually hitting Wikipedia. That’s how we want this function to work in production, but when we’re testing it, this seems a little unnecessary and a little bit time consuming. The solution is to create a Mock Wikipedia, so that when we actually run this test, we don’t have to hit Wikipedia, but our “loadWiki” function can interact with our Mock as if it were Wikipedia.
There’s a node package called “nock” that will help us do this exact thing. We can use “nock” to create mock web servers so that when we test any of our functions that require hitting a web server, we can hit a fake or mock web server instead.
So, the first thing we need to do is install “nock.” Let’s go ahead and go out to our terminal, and I will clear up this remaining terminal screen and I’m going to “npm install nock” and save it to the package json as a dev dependency. So, this will install “nock” which will actually help us mock web servers in our tests. Let’s go ahead and navigate to our exercise files and under the Test folder, go ahead and open up the Tools Spec test.
Now, what we’re going to do is when we test this “loadWiki” function, we area going to create a mock web server in place of Wikipedia. Mocha has a concept called Hooks, and we can add Hooks before or before each test, or after or after each test, and what it will allow us to do is define some code that we should run before we run the whole test suite, or after the whole test suite, or before each test in the test suite, or after each test in the test suite.
So, what I’m going to go ahead and do is I’m not going to worry about a five second timeout. I will delete that line there on 15, and now I’m going to add a “before” function. And in my “before” function, we are going to take in a callback, so this callback is the code that we want to run before running every test in this suite, and before we run every test in this suite, we want to create a mock web server. What I’m going to do is come up to the top here and incorporate “nock, var nock = require(“nock”)” that we just installed.
And now that we have “nock” we can use it in the before statement to create a mock web server. And now I just need to specify my mock web domain name, so we’ll add a “https://en.wikipedia.org” and now we also need to specify which type of request we are mocking, so we are going to actually create a mock for a get request, and if you go to Wikipedia.org and get “wiki/Abraham_Lincoln” you wouldn’t be making that request of Wikipedia, you’re going to be making it of this fake “nock” server.
So, the last thing that “nock” wants is to know what it should reply with. Meaning that, if you make a request for this URL at this route, what should the response be, and we should get a 200 successful response, and now we don’t need to return an entire HTML page, all I’m going to say is “Mock” and we can actually move these down. We can chain these along just to get a little bit more space and some clear code so I can say “Mock Abraham Lincoln.” So now we have gotten in between this test and its request for Wikipedia by mocking a fake Wikipedia server for get requests to Wiki/Abraham Lincoln.
Any code that makes a get request for that server will actually be hitting our mock server instead. The test that makes that request is right here on line 24. Invoking “tools.loadWiki” should actually cause a request to occur for our “nock” server. And the HTML that’s going to be returned is now limited to the string that we defined on line 20. So we can even take this one step further, and instead of expecting the HTML “to.be.ok,” we can actually say this should equal, and what should this equal? “Mock Abraham Lincoln Page.” So when this “loadWiki” functions hits our fake page, the response is going to be “Mock Abraham Lincoln” page.
Once we get a response, this callbacks function should fire and that HTML variable should be set to that mock response. Let me go ahead and save this and navigate out to our terminal, and we’re going to try to run our test again with “mocha” and doing so, our “loadWiki” test passes. Also notice that it doesn’t take time for this test to pass. Because we’re not actually hitting Wikipedia, and waiting for that response page. This test executes immediately because we’re only hitting the mock server, and the mock server’s returning his small string, but this tells us that the “loadWiki” function is behaving as expected.