OK, so let's get started with testing now.
We talked about testing briefly way back at the beginning of this course, and you may have been saying
to yourself, well, wait a second.
He said testing was important, but he's not doing any.
Well, I wanted to get enough code in there that we could actually test things without having to go
back and change it over and over and over.
And we're going to write tests now and we'll continue to write them for the remainder of this course.
Now, the first thing I want to test is my main function.
And if you recall, I said back in the beginning when I was going over testing in the introduction to
go, that my goal would be to not test my main function, to make it as stupid as I possibly could,
and instead test things outside of the main function and just leave the main function alone so we can
do that and we can do it pretty easily and we can do it by creating a new function here on my main DOKO,
I'm just going to call it Run, Func, Run, and it's going to take no parameters, but it's going to
return an error or nil if there is no error.
So at the end I can say return nil because I'm going to have to do that at some point.
And what I'm going to do is take everything from here, from where I initialize my renders and initialize
my handlers all the way up to the beginning and cut it out of there.
And I'm going to just say run.
I shall say error is equal to run.
And I'll check for the error at a moment and I'll paste what I cut out of my main function into my room
run function and it should catch up.
And what I'm going to do here is say if error is not equal to nil, in other words, if the setup failed,
then I want to return.
I want to log fatele.
I just want to stop and print out the error.
OK, so Logoff will write to our terminal and it will stop the application.
It won't go any further.
And that's exactly what I want.
So let's go down here and see are we actually getting any errors because we have to.
Well, we register a God that doesn't throw errors.
We initialize our apter in production.
That's fine.
This is all fine.
None of this throws errors.
Aha.
Here's one where we create our template cash.
Well, if that gets set to non nil, in other words, if that throws an error, I can just return the
error rate here, return error and that won't bother trying to do anything else.
So there now this is testable almost.
There's still some more work to do.
So let's write a test for this.
Let's try to write a test for this.
So I'll come in here to my main folder and create a new file and go file, which I will call main underscore
test Dongo.
And as you recall, anything that has underscore test before the go, that's considered to be a test
file.
OK, so what am I going to do inside my main test?
Well, what I want to do, you think about it, is just func test run.
I want to test that run function that exists over in my main go file this one right here.
So let's write a test for that or see if we can.
And of course, because of the test, it takes a pointer to testing Dorte and it automatically important
testing for me.
That's good.
So let's just say error is assigned run.
Does that work?
Well, let's find out if Iraq is not equal to nil, then what do I do?
T dot error f failed.
I just, you know, er failed run and let's try running it now, I'm going to do all of my testing,
all of the running of the tests in a terminal window.
You can do it in the terminal in your idea if you want to.
But I'm actually going to do it here.
So let me run that test.
Am I in the right folder.
Oh, I am in the right level so I need to go to command web and go test.
And a past perfect no problem.
And if I go test Teshuvah just to get the verbose it runs test run and get past it.
OK, so that was easy and I have not.
Now I know how to test my mind test.
How do I test, for example, middleware here?
I have no surf in here.
I have Sushila.
Is there a way of testing the middleware?
Well, we can try.
Let's just create a new test file.
Middle where underscore tests don't go.
OK, and let's see what we have to test, we have to test no surf and we have to test session lows.
Well, can I call this.
Let's try that.
Let's see if we can flunk test.
No, sir.
He pointed to testing Dorte.
And let's see what we can do.
Well, I could try saying h what what is it written?
Let's see what it returns.
It returns and it be handler.
OK, can I just go h for my handler is assigned no surf and it has to know surf has to take a parameter
and it takes a next HTP handler.
Well where am I going to get one of those.
I need to create a handler to pass to no surf so we can hand me back a handler.
Why I need to create one of those.
Fortunately it's not that difficult to do it.
What I need to do is to take advantage of goes interfaces like we talked about way back in the introduction
to the go language.
So I'm to need some method of setting up the environment before this actual test runs, and that's not
that hard.
So let's go to our Web folder and create a file with a very specific name set up underscore test Testico.
And whatever is in here, we'll actually run before our tests run.
It won't run in our compile program.
It's not part of that, but it will run before our test run.
So in this file, I need to set certain things up.
So what I needed the first of all, is any time you have a set up test, set up underscore test, OK,
it has to have a function and that function has to be called test me.
So func test main and M, it's just my variable name and it's have type testing, not T but M and it
doesn't return anything, but it runs and does certain things.
So what it does here is that we can set up our variables in there if we wanted to, and I'm going to
put os x it.
But before it exits that's supposed to be X exit.
I just says stop but before it does that it's going to run certain things.
Ambigram, it's going to run my tests.
So this says before you start running the tests.
So middleware test or main test, do something inside this function, then run the tests that x and
it also gives me a place to store variables that I might need outside of the test main function.
And here's where I'm going to create an object that satisfies the HTP handler interface.
And it's going to be a type and the type will be my handler.
That's just the name that I choose and it's just a struct.
So that's the type.
Now I need to satisfy the server or satisfy the HTP, the handler interface.
Well, the HP handler interface, we can go look at it here under middleware and find an HTP handler
and there it is and it tells you all about it here right now.
And all we need to do is implement the same methods or the same functions that it does.
And in this case, that's really easy.
So let's go back to setup test and do precisely that.
So I'll create a function.
It will be tied to my handler or.
Yeah, my handler.
So I'll put my variable name in the receiver and it's just a pointer to my handler, OK?
And now I need to have the function with exactly the same names as the ones that are implemented by
HTP handler.
So what does it have?
It has one called Serve HTTP, which we've used in our main function I believe.
And it takes two arguments, a W which is in each feed of response writer and a pointer to you to give
a variable name or a pointer to HTP request.
And I'm not going to return anything.
I've implemented it.
That's all I have to do.
So now I've created this type.
So what can I do with that type?
Well, I can go back to my middleware test, which is over here, and I can actually now populate this
with the information that it needs to have no serve requires.
If I point out it, it requires an issue to be handler.
So all I have to do is create a variable that satisfies the interface for HTP handler.
And I can just go over my H, which is just a variable name that I'm picking and it's a type my handler,
which I defined over in setup test, go right here.
So now that I've done that, I can pass that as an argument.
My H now so my H.
Let's see here.
What do I miss.
Type does not implement HGP handler and serve HGP method has a pointer receiver.
What did I do wrong.
Well in here I need to make this a pointer now.
It's a pointer to that variable so that works.
So now I satisfy the requirements for no serve and I've received an HTP handler back here but I.
I haven't done anything.
How do I test that it's actually a hand that's really the only thing I need to test at this point for
our purposes.
When I call no serve, it should receive an HTP handler or something that satisfies that interface and
it should return something that is also in a [REMOVED] behavior.
So all I can do is just test for it and we can test for that very easily.
We can use our switch statement, which we saw a long time ago, and I'll just use V as my variable
name and that will be assigned the type of H.
So I've now got a switch statement I'm storing in V whatever type h.s.
And as is a switch date, but it has to have these parentheses and I'll put case htp dog handler.
If the type is an HDB handler do nothing.
So I'll just put a comment here.
Do nothing.
This is what we expect.
So if it gets that this should be a code, not a semicolon, if it gets that we've in effect passed
our test, otherwise the default is going to be something as simple as writing an error teig error and
we'll write our error type is and in this case I'm going to type is not HTP dog handler and with that
fails.
So we should be able to run this test.
Now, let's go back and give it a try.
There's an error in here somewhere.
Where is it.
Over here and use variable V so we have V default case HDB handler so I should use it down here.
I'll just put it in here.
I've got to use that variable somewhere so I'll put changes to a format or s print F and inside of that
type is not but is.
And then I'll put in my syntax for that which is simply t you haven't seen that yet, but that just
says print the type and that's what the placeholder for the type sameas percent D is a placeholder for
instance percent s is a placeholder for string's.
This is for V there.
Now we have no error.
So now I should be able to run this test.
Let's try this or go back to my terminal window, clear the screen and go test and everything past.
Good.
So now I've tested that hammer.
No problem.
What else do I have to test in middleware.
Well, I have session load and what does that do that receives and should it be handler at hands back
in HTP handler.
So let's just make sure that a run that's pretty easy to do is pretty much the same thing.
I can just copy this and paste it and change it to test such and load.
And in this case I want to create a handler, but instead of creating a No sirf, I'm going to call
session load and session loads should give back a type and the type should be what it should be.
It should be handler.
Nothing else should change.
So let's try this.
Go run test or go test Dashti.
Everything past, OK, so now I've tested my main function as much as I want to.
I've tested by Middlemore where function as much as I want to now route's how do I test my roots?
I have all these roots.
I'd really like to test those.
Well, it's not that difficult again.
OK, let's go back to our here our web folder and create a new file called Test Ersoy Roots Underscore
Test Dargo.
So it creates that file for me.
And in here it's a package name.
I need to write some test for it.
So let's read it function func test routes and it takes t testing Dorte and it doesn't return anything.
So what do I need to run the routes.
Well, let's go back here and look at them.
I need an app config, a pointer to an app config.
I definitely need that and it has to return a handler.
OK, so what else do we need in here?
Let's just try it out and see what happens.
So route's test.
First of all, I can say var app, which is a config app config.
No problem.
I've created a variable, does not have anything in it and then I can call mux.
I'll just call out my variable name because that's what we're using the roots file and call and pass
it a pointer to my app.
OK, and then switch the monks dot type.
I'm going to just test the type again and run this and say is it of type.
Well what actual type does this return?
Let's go back to our roots and see what it's returning.
Its returning mux and Marks is a pointer to dot marks.
OK, so that's what I should test for.
So Case Star Chheda Mux and it does the import for me do nothing,
test past and let's try our have our default case.
If it's not that then I want to add an error t error and again I'll do format s print F type is not
cheap.
Dot marks type is Pacetti and in there I'll just put the.
So let's see if this works.
Let's try running this test.
Clear the screen.
Go test Dashti.
Everything passed, that's not bad at all.
So have we tested everything we need to test in here?
Let's find out under our Web folder, we have mango.
We're testing our run function and we're testing that right here.
Good.
Under our middleware test, we're testing test, no surf and test session load.
And in middleware, we have no surf and session load.
In route's test, we're only testing the roots while creating the roots of our roots called the roots
function.
So under roots, we have roots that seems good.
So far, that seems to work just perfectly.
So let's see now what our coverage looks like.
A test or a go test cover.
Eighty point nine percent of statements.
That's pretty good.
Well, what about testing a little more and a little more detail?
How do we test to get our coverage as an HTML file?
What if you recall, we do it like this.
We go go and test and then cover profile equals coverage, dot out or whatever you want to call it.
And then we run go tool cover HTML format using coverage out.
We'll see how that works.
Fired up my Web browser and it says, OK, you're not testing your main function.
We knew that this is all tested except for that.
I can live with that because we know that the test failed at that point.
OK, and we look at our middleware that's entirely covered everything that has to be.
And we look at our roots and that's entirely covered.
That's pretty good.
I think that's excellent test coverage for our main package.
So we've tested our main and we've tested our handlers.
Let's move on with some other tests.
We haven't actually tested our hander's.
We've tested aretz.
Let's move on with our handlers in the next section.