>> Hi. So in the last video,
we talked a little bit about getting into unit tests.
So we've covered libraries,
we've covered NuGet packages.
Now, let's make sure our code is actually well-tested.
>> Yeah, you were complaining a little
bit before because I had written what I
kind of thought were tests and you were
probably reasonably not super
impressed because I was just messing around.
They weren't really tests, were they?
>> So back in the C Sharp tutorial series,
we were talking a lot about some exceptions,
and how we hit those,
and when we could avoid them.
So we added these try catch blocks.
Ideally, these should actually be included in test projects.
So let's go ahead and add
our first unit test project to the solution.
>> Okay. So before in the previous video,
we added a library.
So I have an executable that depends on a library.
A unit test is another project type?
>> Yeah, so this will be a third project in our solution.
>> So I'm going to go "Add", "New Project",
and then if I type in test,
there's actually a bunch of different kinds of tests.
I see " MSTest ",
"NUnit Test", "xUnit Test", which one should I pick?
>> Yeah. So for our purposes,
we're going to choose the xUnit Test Project
that uses dot net core.
There are NUnit and MS tests testing frameworks as well.
We can get into more about explaining
those tests in other videos that you can see on YouTube.
>> Okay. So I'll go and say "Next" and we'll
just call it the default, I guess, I don't know.
>> Yeah. That sounds fine.
>> Banking tests. Create. Okay, so
another project has appeared there and there you go.
So by default, I just have,
it looks like a banking test namespace and a fact. I have a fact.
>> Right. So xUnit uses facts attributes at the top of,
you might recognize public void Test1
that looks a lot like a method.
In order to transform it into a test,
we put the fact attribute on it.
>> That attribute is like a posted note that you put on
method and you'll see other attributes
as you go and write code in.NET.
>> Yeah. So you'll actually see immediately
something new popped up at the top of this method.
So that little tiny icon is the code lens test icon.
>> That little thing right there?
>> Yeah, that guy. So from that icon
you can see if the test method has run,
which it hasn't yet or if it's passing or failed.
>> Is there anything we could test?
We just tested like true is true.
Is there anything we can test?
>> Yeah. Let's go ahead and write an assert.
>> Assert?
>> Assert.True.
>> Okay. Assert that something's
true and then it says condition and we know about conditions.
>> Yeah.
>> If statement condition. So we'll just say
assert that it's true it's true?
>> So the test should be passing.
>> Okay. How do I run that test?
>> So there's a few different ways.
You could use "Control RT" which will run
the test or you could use the Copeland's icon.
>> I guess you click on that little icon.
>> Yeah.
Then it pops up and you can run it.
>> Okay. Or I could right-click on the method and run it that way.
So it said it's succeeded and now suddenly it's green.
>> Right.
>> Then something flashed on the left-hand side here.
>> Yeah, that was our Test Explorer.
You can also use
the Test Explorer to run tests to your heart's content.
So the Test Explorer is one place you
can look to see your entire test list.
So right now, we just have one and it's parsing.
So let's add a few more.
>> All right. Let me do this.
How about we go back over here and
I'll just pull these out of here.
>> Yeah, we can start filling that out first.
>> I'll "Control X".
So this we've tidied up our program,
dot cs a little bit.
I'll just fold that in the clipboard.
>> I'm feeling better already.
>> Yeah, it's bad.
Okay. So I just make another fact,
and I can make another test.
>> How about void and call it Test2?
>> Yeah. Then for now,
I'm just going to go and paste again,
and what I'll do is I'll comment these out again.
>> Sounds good.
>> I'm just holding them there.
Again, I can go and say,
where we was commenting?
I think comment selection and you said it was "Control K",
"Control C." That just makes it.
So they're there but they don't do anything.
>> Great. So if you go over to the "Test Explorer"
and expand the banking tests node now,
you can see that
the Test Explorer actually adds a little bit of structure.
So right now it's grouped to a project namespace and then class,
but you can see both tests appearing now.
>> That's cool. It says Unit Test1.
I guess I could click there and say "Rename" and call it like
Basic Test and then presumably the unit test.
Yes see. Now I have basic test.
So I might have lots of different tests.
>> Yeah and since you changed how we define the test,
the old results are gone.
So it's basically as if you added two completely new tests.
>> I see and I'm going to be running tests
and running and changing and running and changing.
So those things on the left side will change a lot.
>> Yes. So It'll actively update as you're running tests.
>> Okay. So when I was messing around earlier,
I was trying to test negative balances,
and I know that if I try to take out more money than is
allowed then it would throw
an exception that that operation is not invalid.
I don't really know how to test that though.
>> Yeah. So let's take the first try-catch block you
have commented out and put it up in our first test.
>> Okay. I know that we need to go and
make our fake account first too.
So I'm going to grab a little bit of code from that as well
and I'm going to say Make an Account.
I'm also wondering will it even know about bank accounts?
>> It doesn't or it definitely going to get some areas.
So just like how we added
a reference to the class library in our Console app,
we'll need to add a reference to
the class library in our testing and projects.
>> Before I right-clicked and I said "Add Reference",
why don't we try something different
this time and I'll click on this,
and we'll let the quick fix to it.
>> Yeah.
>> See.
>> So that's added and I really like that one.
So it added the reference to
the project node in the solution explorer
and it also added
the using statement that we needed to the top of this file.
>> That's cool. Two, three
things that I would have had to do myself.
Now I don't have to worry about them.
>> Yeah.
>> All right. So you had said to comment that
out and let's go and test for a negative balance.
I'm setting up and before I was just I guess trying
something and then catching it
and then basically Console.WriteLine.
Suddenly, it's not only testing it though it just does it.
>> Yeah. So in tests,
you don't really need a console.WriteLine
because whether or not the test is passing or failing,
it's really the main feedback mechanism you want.
You don't want to have to go check the console to
see if the test passed and what not.
>> Okay.
>> So instead of making a Console Write Line to actually check it,
let's actually make an assert.
>> Okay. So we make an account,
I want to make a little room here,
and then we will say assert, okay.
Assert what? We were asserting
true and false and things like that.
What can I assert in the context of an exception?
>> So we want to make sure it throws an exception.
So we'll use assert.throws.
>> Okay. I know that it throws a invalid operation exceptions.
I know that that's the thing. All right.
Then this is a syntax I don't
think that we've ever seen before because we're
going to basically do that work inside
of this method here this throws, right.
>> Right. We're going to go ahead and have it return.
>> We're going to go ahead and do an anonymous function.
So we're basically doing
this syntax which you'd never seen before.
>> Right.
>> This is a weird one and we'll break it down, right.
So let's go and just copy paste that.
I'm just using the cursor's select
that and hopefully I'll get this right.
You see how I'm not freaking out because
even though I'm being told there's errors,
I know I'm not done yet.
>> Yeah.
>> Right, that's a good reminder.
See those errors went away.
So let's break this down.
We're saying assert.throws and I can hover over throws,
and you see how they've got the little angle brackets there.
That's the type where it was a cup of tea.
This is it throws a type of
invalid operation and then
the test code goes in what's called an action.
The way you say an action is you made
this little funny rocket ship.
It's like and if you turn
your head and it looks like a rocket ship.
>> Yeah, I see it.
>> So there's your parenthesis and then your rocket ship
and it points to the code that's going to do the work.
Now, if your fancy like some people,
I've seen folks do this all on one line.
Yeah, and I don't know about you but I find that hard to read.
So I think I'll put that on
two lines even though it's technically I guess one line code.
>> Yeah, sounds good. So with this statement,
we're basically telling the test that, hey,
we expect when we execute this line, account.MakeWithdrawal,
withdrawal with these inputs,
that we expect it to throw an invalid operation exception.
So in this test,
we're asserting that it's going to throw
this and if we don't, it would fail.
>> Okay. So we assert that we're expecting this.
This is not a bad thing that this exception is happening.
>> No, we want it to happen because we want people
to know that they are overdrawing their account.
>> So we give you $10,000,
we take our 75,000.
I'll then right-click and I'll say "Run Test".
Okay. So now it's going to run those tests.
Build succeeded. You can see it's
actually spinning over here, something's happening.
>> Great. So that was our Test2 method, so yeah.
>> I didn't click on Test1,
so Test1 didn't get involved, and that's okay as well.
I've seen it succeed though but I never really saw it not succeed.
>> Right. I don't want to make it fail.
So that would be, like,
yes, we could change the withdrawal not to be.
>> We can take out less money?
>> Yeah, less than the,
so that it won't actually overdraw the account.
>> Okay. Right-click, "Run Test".
That right-click Run Test is very convenient.
>> Yeah.
>> All right. So it's right, look at that.
>> So it now failed because it did not throw
the exception that we expected those inputs to throw.
>> Expected operation, actual, nothing bad happened.
>> Nothing bad happened when it was supposed to.
>> Okay. So let me see if I can do this by myself then.
>> Okay. No help.
>> I'm going to take this code here which is the code from before,
I make another fact,
and this is a great thing about unit testing.
You want to make lots of these, right.
Like you can't have two name.
I probably should named them better too.
You can have as many unit tests as you want, right.
>> Yeah. Descriptive names are always pretty helpful.
>> Yeah. I'll fix that later.
So I'm going to comment that.
So let me think here, argument out of
range so I don't need the try,
don't need the console dot write line.
You said I do need my argument out of range
and we're going to go and
create something and that's going to be our action.
So let's look at the code above,
assert.throws argument out of range,
then I'm going to open my parenthesis,
and I'll close it down here,
and then I'll do my rocket ship
for my action and then I'll just take
this and stick it in here.
Now this guy's mad because this doesn't exist.
This concept of a Var doesn't exist in this context.
So we've got a little bit of an interesting thing
where we want to actually make something.
We're going to do a constructor
and there's no good way to do that.
I don't really need to save it though.
It doesn't really matter if I save it.
So I don't need that Var.
So that should work, let's find out.
Actually instead of run test, can I run them all?
>> Yeah, you can definitely run all tests.
>> Okay. How I do that?
>> So you can click the,
in the Solution Explorer,
yes, the double arrow.
Sorry, in the Test Explorer.
>> In the Test Explorer, run all tests?
>> Yeah.
>> We have that other one at the top that's still
tests that true is true. Hey, look at that.
Now let's see if this,
I want to watch it fail too so I'm going to make
a valid one as well and then I'll run all tests
because it's not really a test unless you see
it go wrong as far as I'm concerned. Up there we go.
>> That's a very good observation.
So I do know there's so many
different on testing strategies and advice out there.
I have heard people say if they
don't see a test fail they don't trust it.
So they actually want to make sure they can make the test
fail because if it just always passes as you're developing,
you might have never
input something that would actually caused it to fail.
>> Okay. So while you were talking I just went and
renamed those and I just made
them what I thought would be nice names.
True is true, can't take more than you have,
and need money to start.
>> That sounds good.
>> So that's pretty cool. That gives me a sense
of confidence about my things.
So we can really just test all the time.
I could write, am I going to end up
writing more tests than I actually have code?
>> It's possible. So it all depends
how much testing someone wants to do and what code coverage.
That's how much of your code is covered by certain test methods.
All of that decision is up to you as the designer of your program.
>> We're just scratching the surface of
the things that Visual Studio can do with testing but
I hope that you start writing lots and lots of tests
and maybe you'll start doing test-driven development.
Unlike us, you'll write your tests
first and that will then inform your design.
But now that we've got our application
mostly working, in the next video,
let's publish it and maybe run it on
maybe both Windows and/or Linux.