ok so let's have a talk about some other
j unit assertion methods first one
assert not equals
so we can use this instead of assert
equals when we don't want the actual
value to be equal to a specific value
assert array equals when we want to
verify the value of an array we have to
use the assert array equals method
now the assert equals method won't work
in that scenario because it will only
consider 2 arrays to be equal if they
actually are the same instance so the
assert array equals method considers two
arrays equal when they're links are the
same and every element in both arrays
are the same as well and in the same
order next assert null and assert not
null we can use these methods to check
for null and non null values we can use
assert equal to check for null but
as with the assert true and assert
false methods using assert null and assert
not null makes the intention
clearer and we only have to pass the
actual value to the method assert same and
assert not same now use these when we
want to check whether two instances are
the exact same instance remember that
these assert equals method uses the
equals method to test for equality now
the assert same method compares the
object references only and lastly assert
that now this method compares the actual
value against a matcher and by the way
this is not a matcher in the jdk but a J
unit matcher class and think of this is
something that's more powerful than the
other assert methods since we can
compare the actual value against a range
of values and note that this method only
became available in j unit 4.4 alright
so it's time to move on now to look at
more annotations that we can use now I
said that we want to start each test
fresh and so we're creating a bank
account instance at the beginning of
every test and the exception to that was
when i ran that test in the previous video
to test to see whether the bank
accounts checking was the same as the
savings so we're using the same
values for the bank account in every
test instead of writing the same line of
code in each test what we can do is use
a method that has the at before
annotation now a method with the at
before annotation is run before every
test so let's try this out by changing
the code to use a setup method what
we're going to do is remove the creation
of the bank account instance from our
test methods and instead what we'll do
is we'll have an instance variable
called account in this class and then
the setup method will create the
instance and set the instance variable
alrights at the top of the bank
account test class we're going to put it
up in there so we're going to do...
....
now what we're going to do is go through
the other methods and remove the
creation of the account of the bank
account because we're not gonna need
that anymore so remove it entirely now
that's from the deposit method also for
the get balance _ deposit method
same with the get balanced withdraw
method and finally to the is
checking_true method
basically as you can see now we're
running setting that up the new field
that we've defined here on line 12 is
being instantiated with a new object in
this setup method so the at before
annotation the at org.junit. before
is telling the junit
framework to run this method
set up every time you run the tests so
lets actually just now run this to see
what happens
so I'm going to make sure that bank account
test is still selected click on run
we should get the same results last time
in the each test will run and noting that
the same four methods have succeeded in
the withdrawal hasn't that's because we
haven't really implemented that yet but
notice also here we've got this running
a test coming up four times and if we
scroll up we can see the fifth time and
the reason that it's failed one of those
times is of course the withdrawal method
has still just got that fail code in
there because we haven't implemented it
yet
the bottom line is that you can see now
that this setup method has been executed
each time a method is tested prior to
that tested being executed so therefore
we are getting it in this case and new bank
account object being instantiated on line
16 every time a test runs so
that's really great when you want to
some code to be executed
each time a test runs but what about the
case where we want to perform setup code
before the tests but we only want to set
up code to be run once in other words we
don't want to run up before every test
and an example that might be when we
want to read data that all the tests
were used from a database or file or
perhaps we may want to open a network
socket or do some other setup that we
really want to do once per run
instead of once per method invocation so
in that scenario would use the org. junit
. before class annotation and
then we use the org.junit . after
class annotation to run cleanup code now
the app before class method will run
before any the test cases in the test
class and the after class method and
surprisingly will run after all the
tests in the test class have completed
in this case the methods have to be
declared as public static methods and
they must return void so a little bit
different to how we set up the
other classes so let's go ahead and add
one so i'm going to set one up here
before class i'm going to set up here so
...
....
...
...so I don't
like to put the two before
methods at the top of the class and the
after i like to put down the bottom this
so its in a logical order was
logical to me
let's do that for the after so....
....
....now remember here that
the name of the method isn't important
before class or after class the
annotation is what junit is using
to determine whether to run that method
whether it's going to be run at the
start of the test methods are at the end
so let's actually run this if you
have a look at the results you can see
that we got the messages this executes
before any test cases only once and
likewise only ones after we've got other
tests in there got the we added as a
result of adding the setup method as well
using the . before
annotation but depending on the timing
the statement printed by before
class may actually appear in the console
after the statement printed from the
setup method and you can see that is the
case here we printed here this is
the last two messages printed this
executed before any test cases and
execute after but this doesn't actually
reflect the order of execution
what is happening is that the print
statements are spooled to an IO thread
and so they may appear in the console out
of order and they're actually doing that
as you can see in this scenario so just
to show this lets actually add a
static int variable to our class and
also a method we're going to annotate with
add after each time a method in our
class runs what we're going to do is
print out the value
that variable also increment by 1 so
that we can actually see a true test of
when these methods are being executed so
i'm going to create an instance variable
here
....
because we only want one instance
of that variable when we're going
through all these methods so we're going
to show the value before the classes are
executed
we got our set up per normal what we
want to do is get into the bottom we want
to add an after so I'm going to add the
after shortly but before we do that in
the after class
let's also add account there as well
....
...
....so this will be executed this
method after each unit test is finished
in a similar way to the way that the
setup method was executed before every
test so...
....
...
okay so that should be that so now if we
run our tests again we should be able to
keep track of the count now as it goes
through so looking at the output we've got
count equals one running a test and down
the bottom we got this
executed before any test cases count
equal 0 so that's actually the
output from our before class method
noting that it actually is set to show
the value of count which will be 0 in
this case and then increment after that
and you can see that each other tests
went through as a test was executed
count is 12345 and the last one
count equals six was executed in the
after class method as you can see there
with the output on line
54 that's confirmation that even though
the output is showing a different order
the methods are being run in the order
that I specified ok so let's go ahead
and update the code in the bank account
withdraw method and go back to our
bank account class and have a look at
this withdraw method that we've got
here on line 35 right now we're not
using that branch parameter and you can
see that intellij telling us
that the perimeter branch is never used
but let's suppose this bank doesn't
allow its customers to withdraw more
than five hundred dollars from an ATM
now the customer tries to withdraw more
than 500 and they're not using a teller
at a branch we need to thrown an
illegal argument exception
we're gonna make a bit of a change here
we're going to put a test in first so if
....
...
...and then
we leave the other code at the bottom as is
because the code will only be executed if
that doesn't occur put a semicolon to
complete that line
alright so we now testing to make sure
that we are only able to deal withdrawal
if the amount is less than or equal to five
hundred dollars and it's a branch
otherwise as you can see this scenario
is going to throw new
illegalargumentexception let's go back
and update the code in the bank account
. withdraw test method then coming
back here to our bank account test
we got our withdraw methods at the
moment we haven't got anything written
in their for so go ahead and replace
that now i'm going to give another fail
there and we'll put....
....
...
the test here is to check to see whether
we can withdraw more than five hundred
dollars and we are at a branch and the
true on line 32 means that we are
withdrawing the money from a branch so
if we run this now run our tests you see
at this point now all our test have
actually passed and you can see we've
got confirmation on this side as well
and we can see now that there's no
problems and we can see all the output
now interestingly enough in the right
order this time you notice how that the
output is now appearing in a better
order than what it was when we have
tests failure previously alright so
let's change that will change the name
of this one back up through withdrawls say
withdraw...
....
...bearing in mind that we've added the
code in the method in bank account . java
to throw an exception if that's the case
so now if we actually run this you can
see what's happening we've got an
illegal argument exception which is to
be expected because of the amount that
we try to withdraw an ATM exceeded the
value that we specified in bank account
java in the withdrawal method but the
problem here though is that the test
actually passed in other words we want
the method to throw in an illegal
argument exception when branches false
and the amount is greater than 500 so
how do we handle this to correctly
indicated the test has passed
in this scenario we were expecting an
exception to be thrown we actually have
to make a modification to the annotation
for the method I'm going to do that as
follows down here in the withdraw
branch what we do is we put
....
...
so now when we run we should find that all
our test methods will actually pass and
see at this point now because we've told
the method to expect an
illegalargumentexception we no longer
get the exception showing and all our
tests are now succeeding and working
properly
alright I'm going to finish the video
here now in the next video we're just
going to come up with another little bit
of a scenario to optimize this withdraw
underscore not branch method and going
to show you the old way of testing
exceptions that I used to have to do in
older versions of j unit see you in the
next video