SQA Final Exam Prep UPDATED ACTUAL Exam Questions and
CORRECT Answers
TUFs are - features that you want to fake using stubs (because they take too long to set up to
work correctly, or test, or testing them causes unwanted side-effects
examples of TUFs - - printing to console
- reading / writing from a database / to a filesystem
- access a diff program or system / the network
TUCs are - methods that are hard to fake using stubbing or overriding
stubbing def - replacing a method in a mocked object using Mockito
overriding def - overriding a method in a "fake" class that subclasses real class
TUCs examples - - object constructors / destroctors
- private methods
- final methods
(the above four are impossible to override)
- static methods: impossible to override or to stub (since static methods are called on classes not
objects)
so what does no TUFs inside TUCs mean? - do not put code that you want to fake (TUFs) inside
methods that are hard to fake (TUCs)
,make it easy to satisfy preconditions - - depnednece on external data is bad for testing
external data examples - - val of global vars
- val extracted from a global data structure
- val read from a file / database
- basically any val that you did not pass in as args
- aka side-effects
pass in data using args (will need less external data) and for the remaining external data - -
segregate hard-to-test code w/ side-effects into a small corner
- keep as many methods pure as possible
make it easy to reprouce - - dependence on random data is bad for testing
- random data = impossible to reproduce result
if you pass in Die d var, - you can do
int dieRoll = d.roll();
(above is better)
than
int dieRoll = (new Die()).roll();
with int dieRoll = d.roll(); you can - mock Die and stub d.roll():
,or you can just pass in dieRoll - public Result playOverUnder(int dieRoll) { if (dieRoll > 3) {
return RESULT_OVER; } else { return RESULT_UNDER; } }
and don't have to mock or stub anything yay!
when we pass in instances of room into the house parameter, we can mock and stub more easily:
public class House {
private Room bedRoom;
private Room bathRoom;
public House(Room r1, Room r2) { bedRoom = r1;
bathRoom = r2;
}
public String toString() {
return bedRoom.toString() + " " + bathRoom.toString();
} } - Room bedRoom = Mockito.mock(Room.class);
Room bathRoom = Mockito.mock(Room.class);
House house = new House(bedRoom, bathRoom);
dependency injection def - passing a dependent object as arg (instead of building it internally)
dependency injection features - - makes testing easier by allowing you to mock that object
- also what allowed us to mock the Die object for repproducibility
- has other software engineering benefits like decoupling the two classes
decoupled def - it is easy to switch out one class for another
, how to approach legacy code - - pinning tests
- look for seams in the code
- and refactor
pinning tests - - test done to pin down existing behavior
- existing behavior may differ from expected behavior
- pin down all behaviors, including bugs and al, before modifying
- don't want to modify "defective" behavior because your software can break
what is a seam - place where two code modules meet where one can be switched for another
without having to modify source code
seams important for pinning tests - - pin down the behavior of each unit in legacy code
- seam is where fake objects can be injected to localize the unit tests
not modifying source code because - - pinning tests are testing the legacy code as is (lol)
- if we modify code, there is a danger that we may be changing behavior
legacy code w/o seam - String read(String sql) { DatabaseConnection db = new
DatabaseConnection(); return db.executeSql(sql);
}
hard to unit test since we are forced to work w/ a real DB connection
legacy code w/ seam - String read(String sql, DatabaseConnection db) {
return db.executeSql(sql);
}
CORRECT Answers
TUFs are - features that you want to fake using stubs (because they take too long to set up to
work correctly, or test, or testing them causes unwanted side-effects
examples of TUFs - - printing to console
- reading / writing from a database / to a filesystem
- access a diff program or system / the network
TUCs are - methods that are hard to fake using stubbing or overriding
stubbing def - replacing a method in a mocked object using Mockito
overriding def - overriding a method in a "fake" class that subclasses real class
TUCs examples - - object constructors / destroctors
- private methods
- final methods
(the above four are impossible to override)
- static methods: impossible to override or to stub (since static methods are called on classes not
objects)
so what does no TUFs inside TUCs mean? - do not put code that you want to fake (TUFs) inside
methods that are hard to fake (TUCs)
,make it easy to satisfy preconditions - - depnednece on external data is bad for testing
external data examples - - val of global vars
- val extracted from a global data structure
- val read from a file / database
- basically any val that you did not pass in as args
- aka side-effects
pass in data using args (will need less external data) and for the remaining external data - -
segregate hard-to-test code w/ side-effects into a small corner
- keep as many methods pure as possible
make it easy to reprouce - - dependence on random data is bad for testing
- random data = impossible to reproduce result
if you pass in Die d var, - you can do
int dieRoll = d.roll();
(above is better)
than
int dieRoll = (new Die()).roll();
with int dieRoll = d.roll(); you can - mock Die and stub d.roll():
,or you can just pass in dieRoll - public Result playOverUnder(int dieRoll) { if (dieRoll > 3) {
return RESULT_OVER; } else { return RESULT_UNDER; } }
and don't have to mock or stub anything yay!
when we pass in instances of room into the house parameter, we can mock and stub more easily:
public class House {
private Room bedRoom;
private Room bathRoom;
public House(Room r1, Room r2) { bedRoom = r1;
bathRoom = r2;
}
public String toString() {
return bedRoom.toString() + " " + bathRoom.toString();
} } - Room bedRoom = Mockito.mock(Room.class);
Room bathRoom = Mockito.mock(Room.class);
House house = new House(bedRoom, bathRoom);
dependency injection def - passing a dependent object as arg (instead of building it internally)
dependency injection features - - makes testing easier by allowing you to mock that object
- also what allowed us to mock the Die object for repproducibility
- has other software engineering benefits like decoupling the two classes
decoupled def - it is easy to switch out one class for another
, how to approach legacy code - - pinning tests
- look for seams in the code
- and refactor
pinning tests - - test done to pin down existing behavior
- existing behavior may differ from expected behavior
- pin down all behaviors, including bugs and al, before modifying
- don't want to modify "defective" behavior because your software can break
what is a seam - place where two code modules meet where one can be switched for another
without having to modify source code
seams important for pinning tests - - pin down the behavior of each unit in legacy code
- seam is where fake objects can be injected to localize the unit tests
not modifying source code because - - pinning tests are testing the legacy code as is (lol)
- if we modify code, there is a danger that we may be changing behavior
legacy code w/o seam - String read(String sql) { DatabaseConnection db = new
DatabaseConnection(); return db.executeSql(sql);
}
hard to unit test since we are forced to work w/ a real DB connection
legacy code w/ seam - String read(String sql, DatabaseConnection db) {
return db.executeSql(sql);
}