We know from introductory coding that we must fix all compile errors before code is usable.
But bugs also lurk behind compiler warnings. Therefore, we want to resolve all warnings. We'll learn (later) that there are rare cases where we will suppress (ignore) certain warnings.
For this example we assume compiler errors have already been taken care of -- thus we focus on warnings.
In unit test, the compiler error is "The method newInstance() from the type City is not visible".
/**
* Conduct a smoke test for the construction of
* a City with no args
*/public void test_newInstance() {
prn("\n-- test_newInstance --");
City city = City.newInstance()←Method not visible ;
prn(city.toString());
}
Investigation
In the unit we identify the problem shown.
protected←Method is not public static City newInstance() {
Bug-Fix: Add Keyword 'public'
In unit, make bug-fix shown.
protectedpublic←Change to public static City newInstance() {
Exception NullPointerException←A null pointer exception occurred
test_newInstance(CityTest.java:16)←The file and line number of the exception
main(CityTest.java:41)
Inspect Exception
Open up CityTest.java
Go to the provided line number (from prev step)
public void test_newInstance() {
prn("\n-- test_newInstance --");
City city = City.newInstance();
prn(city.toString());←The exception occurred here!
}
Infer Bug Location
Per the null pointer exception, the var 'city' must be null.
Therefore, "City.newInstance()" must be returning null
public void test_newInstance() {
prn("\n-- test_newInstance --");
City city = City.newInstance();←#2 - therefore this must return null
prn(city←#1 - the exception tells us that 'city' must be null .toString());
}
Inspect Bug
Open City.java
Go to the method "newInstance"
The bug is obvious, as shown.
/** Returns new City object with
name "Unnamed" and location (0, 0) */public static City newInstance() {
return null;←Oops this is a problem
}
Fix Bug
Fix bug as shown
/** Returns new City object with
name "Unnamed" and location (0, 0) */public static City newInstance() {
return null;return fromNameLatLong("Unnamed", 0, 0);←Corrected code
}
Exception NullPointerException←A null pointer exception occurred
City.<init>(City.java:38)←The file and line number of the exception
City.fromNameLatLong(City.java:23)
City.newInstance(City.java:29)
CityTest.test_newInstance(CityTest.java:15)
CityTest.main(CityTest.java:41)
Per the exception, we infer that the ivar 'location' must be null
private City(String nm, double lat, double lon) {
this.name = nm;
this.location←Ivar "location" must be null .setLatitude(lat);
this.location.setLongitude(lon);
}
Fix Bug
Not initializing an ivar is a common bug. Ivars are often initialized during construction.
We fix the bug as shown.
private City(String nm, double lat, double lon) {
this.name = nm;
this.location = GeoLocation.newInstance();←Add this line to initialize the ivar
this.location.setLatitude(lat);
this.location.setLongitude(lon);
}
Just a tiny bit of test code overpowered a large number of showstopper bugs!
Any of of the identified showstopper bugs would have rendered the unit code unusable.
Fixing these bugs gives us a much higher level of confidence that our code runs.
public void test_newInstance() {
prn("\n-- test_newInstance --");
City city = City.newInstance();
prn(city.toString());
}
public void test_fromNameLatLong() {
prn("\n-- test_fromNameLatLong --");
City city =
City.fromNameLatLong("Brooklyn Center", 45.076076, -93.332728);
prn(city.toString());
}
Bug Summary
1/16/2022
Unit: City.java
UnitTest: CityTest.java
===========================================================
Resolving Compiler Warnings (Unit)
-------------- Bug Notes --------------
The warning was that method param "nm" was not used
in method "MyCity(String nm, double lat, double lon)".
The fix was to set the ivar "name" with the param "nm"
(i.e., to use the param properly).
===========================================================
Bug Search via Compiler Errors (in Unit Test)
-------------- Bug Notes --------------
The UnitTest compiler error was that the package "model.geography"
could not be resolved.
The bug was that, the unit package was incorrectly
named "mygeography".
The bug-fix was to rename the unit pacakge
from "mygeography" to "geography".
-------------- Bug Notes --------------
The UnitTest compiler error was that "model.geography.City"
could not be resolved.
The bug was that the unit file name and class name
were both incorrectly named "MyCity".
The first bug-fix was to rename the file "MyCity.java" to "City.java".
The second bug-fix was to edit "City.java" and change all refs
from "MyCity" to "City".
-------------- Bug Notes --------------
The UnitTest compiler error was that
"model.geography.City" is not visible.
I determined that the bug was that, in the unit,
the class header was missing the access modifier "public".
The bug-fix was to add "public" to the class header:
public class City
======================================================================
Bug Search via Running Unit Test
-------------- Bug Notes --------------
This was an interesting one.
When running the unit test, this exception occurred:
A null pointer exception occurred
On this line (in the unit test):
prn(city.toString());
I could infer that city must be null.
The previous code line is:
City city = City.newInstance();
prn(city.toString());
Therefore "City.newInstance()" must be returning null.
I investigated the unit and found that yes
indeed it was returning null (not good):
return null;
The bug fix was to return the expected object:
/** Returns new City object with name "Unnamed" and location (0, 0) */
public static City newInstance() {
//return null;
return fromNameLatLong("Unnamed", 0, 0);
}
-------------- Bug Notes --------------
Another fun one.
When running the unit test, this exception occurred:
A null pointer exception occurred
On this line (in the unit):
this.location.setLatitude(lat);
I could infer that the ivar "location" must be null.
Therefore, the ivar "location" must not have
been initialized.
The bug fix is to properly initialize the ivar before
using it:
was to return the expected object:
this.location = GeoLocation.newInstance();
this.location.setLatitude(lat);
Unit Testing
(Chapter 202 - Unit Testing - Smoke Tests - Bug Finding)