unit testing - a&bp cc
TRANSCRIPT
![Page 1: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/1.jpg)
Unit Testing the right wayExpressive, useful, and maintainable testing
![Page 2: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/2.jpg)
The Red Line
Goal of Testing
What to Test
Fixtures
Mocks
Assertions
![Page 3: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/3.jpg)
The Red Line
Goal of Testing
What to Test
Fixtures
Mocks
Assertions
![Page 4: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/4.jpg)
GOALS OF TESTING
![Page 5: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/5.jpg)
100% Code Coverage
Test coverage is a useful tool for finding untested parts of a codebase. Test coverage is of little use as a numeric statement of how good your tests are.-- Martin Fowler
![Page 6: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/6.jpg)
public static String foo(boolean someCondition){ String bar = null; if (someCondition) { bar = "blabla"; } return bar.trim();}
100% Code Coverage
assertEquals("blabla", foo(true));
assertEquals("blabla", foo(false));
Line Coverage 100%
Bug Coverage 0%
![Page 7: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/7.jpg)
Reduce Costs
Most of our time is spent on debugging and fixing bugs.Bugs - if not fixed soon in the development process - cost a lot more than
the development itself
Google est. bug cost when fixed at:Development time $5Automated build time $50Integration testing time $500System testing time $5000
![Page 8: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/8.jpg)
Tests as documentation
Tests have to be…
1. comprehensive
2. run often and work
3. written to be read
![Page 9: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/9.jpg)
Tests as documentation
Method names are important to keep tests readableWhile a very subjective topic, a good practice can be:
dividesAmountByFactorthrows_Illegal_Argument_Exception_When_Dividing_By_Zerothrows_exception_when_dividing_by_zero
private double amount;
public double divide(double factor){ if (factor == 0) throw new IllegalArgumentException(); return amount/factor;}
![Page 10: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/10.jpg)
Tests as documentation
● Arrange● Act● Assert
● Given● When● Then
![Page 11: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/11.jpg)
Tests as safety net for refactoring
![Page 12: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/12.jpg)
Tests make you think about your implementation
▪ Tests often trigger refactors and even redesigns
▪ Tests make us really think about the requirements
▪ Tests make us find gaps in the requirements
![Page 13: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/13.jpg)
Conclusion
Write unit tests to…
… reduce costs / save time… be able to confidently refactor… look at your technical design from a different angle… look at your requirements from a different angle
![Page 14: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/14.jpg)
The Red Line
Goal of Testing
What to Test
Fixtures
Mocks
Assertions
![Page 15: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/15.jpg)
WHAT TO TEST
![Page 16: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/16.jpg)
Test isolated units
Keep level of collaboration the smallest possible in units under test
![Page 17: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/17.jpg)
Test isolated units
Smallest possible
![Page 18: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/18.jpg)
Test isolated units
Test in complete isolation
![Page 19: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/19.jpg)
Test isolated units
No knowledge of implementation details of called method of collaborator
![Page 20: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/20.jpg)
Test isolated units
How ?Extensive use of mocked-out collaborators in non-leaf objects/classes
![Page 21: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/21.jpg)
Test isolated units
It results mostly in one test-class per classe.g: MyClass and MyClassTest
![Page 22: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/22.jpg)
Test isolated units
Advantage:Less tests to writeSmaller tests to writeLess complicated setup of fixturesProbably all branches covered quickly
![Page 23: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/23.jpg)
Boundary Cases
Test cases that cover the full spectrum of possible values.
Example 1:A method that accepts only int values between 0 and 100
public void compute(int value){}
Test with -1, 0, 10, 50, 100, 101, 'A'
![Page 24: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/24.jpg)
Boundary Cases
Example 2:A method that removes a character in a String text
public String remove(String text, char ch)
1. Test for null text2. Test for empty text3. Test for character which is not in String4. Test for characters which comes during start, end or middle of String5. Test to cover if text String contains just one character which is equal or not equal to the
to be removed one6. Test with String contains just one character multiple times
![Page 25: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/25.jpg)
Branches
Every time that a different path of execution can be triggered results in a different branch
Basically: if, else, for, while, do blocks and even collaborators
if(condition){
}2 branches : if true and if false
![Page 26: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/26.jpg)
Branches: Cyclomatic complexity
Mathematical result of a formula to calculate the complexity of a piece of code.
![Page 27: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/27.jpg)
Branches: Cyclomatic complexity
Start with a count of one for the method. Add one for each of the following flow-related elements that are found in the method.
Methods Each return that isn't the last statement of a method
Selection if, else, case, default
Loops for, while, do-while, break, and continue
Operators &&, ||, ?, and :
Exceptions catch, finally, throw, or throws clause
Threads start() call on a thread. Of course, this is a ridiculous underestimate!
![Page 28: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/28.jpg)
Branches: Cyclomatic complexity
If this number is higher than 10 it becomes nearly impossible to test.
“Impossible to test” = impossible to have full branch coverage
![Page 29: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/29.jpg)
Branches: Cyclomatic complexity
Keep this number low !!How ?
CLEAN CODE!!!!
![Page 30: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/30.jpg)
Branches: Cyclomatic complexity
Where?SonarQube calculates this out of the box
![Page 31: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/31.jpg)
Code Coverage
Expresses the amount of production code that is covered by automated tests
![Page 32: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/32.jpg)
Code Coverage
![Page 33: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/33.jpg)
Code Coverage: Tools
JaCoCo: replacement for Emma, fully supports Java 7 and 8, used by Sonar, EclEmma(used to be based on EMMA), Jenkins, Netbeans, IntelliJ IDEA, Gradle
Clover: Atlassian → commercial
Cobertura
![Page 34: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/34.jpg)
Conclusion
What to test :▪ Completely in isolation▪ All Boundary cases▪ All branches
Be aware of :▪ Cyclomatic complexity
▪ SonarQube calculates it out of the box for you▪ Branch coverage
▪ Calculation possible by ▪ Jacoco, Emma, Clover, Cobertura
![Page 35: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/35.jpg)
The Red Line
Goal of Testing
What to Test
Fixtures
Mocks
Assertions
![Page 36: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/36.jpg)
FIXTURES
![Page 37: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/37.jpg)
Definition (non-software)
A Fixture in non-software development is e.g.: the setup of a controlled environment to test the functioning of a piece of hardware
![Page 38: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/38.jpg)
Definition (software)
A fixed state of software under test used as baseline for running tests = test context
Preparation of input data and setup/creation of fake or mock objects
![Page 39: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/39.jpg)
Definition (software)
Main benefit:It avoids duplication of code necessary to initialize and clean up common
objects
![Page 40: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/40.jpg)
Use in JUnit
From Junit 4 on there are Java 5 annotations for setting up Test fixture:@Before, @BeforeClass, @After, @AfterClass
![Page 41: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/41.jpg)
@Before, @BeforeClass, @After, @AfterClass
@BeforeClass
public static void prepareSomeResources()
@Before
public void setUpFixtureForAllTests()
@After
public void freeResourcesAfterEachTest()
@AfterClass
public static void freeResourcesAfterAllTestsRan()
![Page 42: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/42.jpg)
ObjectMother
![Page 43: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/43.jpg)
ObjectMother
Factory for creating fixtures that are used in several test classes.
Catchy name thought of at thoughtworks
http://martinfowler.com/bliki/ObjectMother.html
![Page 44: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/44.jpg)
ObjectMother
private PsychoKiller hanibal;
@Before
public void setupFixtureForHanibalLastKill2DaysAgo(){
hanibal = new PsychoKiller();
hanibal.setFirstName(“Hanibal”);
hanibal.setLastName(“Lecter”);
hanibal.setLastKillDate(current - 2 days);
}
![Page 45: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/45.jpg)
ObjectMother
private PsychoKiller hanibal;
@Before
public void setupFixtureForHanibalLastKill2DaysAgo(){
hanibal = PsychoKillerMother.getHanibalLastKill2DaysAgo();
}
@Test
public void returns_true_if_less_than_4_days(){
assertTrue(hanibal.killedRecently());
}
![Page 46: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/46.jpg)
Conclusion
▪ Use Fixtures to reduce code duplication
▪ In JUnit 4 : @Before @BeforeClass @After @AfterClass
▪ ObjectMother: to help keeping setup of fixtures small and concise and
in one place so reusable for other test-classes
![Page 47: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/47.jpg)
The Red Line
Goal of Testing
What to Test
Fixtures
Mocks
Assertions
![Page 48: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/48.jpg)
MOCKS
![Page 49: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/49.jpg)
Why?
Mocking, Spies, Stubs, Doubles & fancy buzzwords
![Page 50: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/50.jpg)
Isolate the code under test
Test one object, not the collaborators !
![Page 51: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/51.jpg)
Speed up test execution
Canned replies are fast !
![Page 52: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/52.jpg)
Make execution deterministic
Less variables means more control !
![Page 53: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/53.jpg)
Simulate special condition
Don’t stick to the happy path.
![Page 54: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/54.jpg)
Gain access to hidden information
Can you see The Hidden Tiger?
![Page 55: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/55.jpg)
Our example codebase
Fancy cars !
![Page 56: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/56.jpg)
Codebase: Car
public class Car {
public void setEngine(final Engine engine) {...}
public void start() {...}
public void stop() { … }
}
![Page 57: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/57.jpg)
Codebase: Engine
public interface Engine {
void start();
void stop();
boolean isRunning();
}
public class DieselEngine implements Engine;
![Page 58: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/58.jpg)
GITHUB!
https://github.com/pijalu/mocktype
Play along !
![Page 59: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/59.jpg)
Dummy|Fake|Stubs|Spies|Mocks
![Page 60: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/60.jpg)
Dummy
Dummy objects are passed around but never actually used. Usually they are just used to fill parameter lists
![Page 61: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/61.jpg)
POJO Dummy
public class TestMockDummy {
final Engine dummyEngine = new DieselEngine();
Car testedCar = new Car(new DieselEngine());
@Test(expected = IllegalStateException.class)
public void testExceptionIfCarStarted() {
testedCar.start();
testedCar.setEngine(dummyEngine);
}
}
![Page 62: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/62.jpg)
Fake
Fake objects have working implementations, but usually take some shortcut which makes them not suitable for production
![Page 63: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/63.jpg)
POJO Fake
private final Engine fakeEngine = new Engine() { boolean started=false;
@Override
public void stop() { started=false; }
@Override
public void start() { started=true; }
@Override
public boolean isRunning() { return started; }
};
![Page 64: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/64.jpg)
POJO Fake (cont)
…
private final Car carWithStartableEngine = new Car(fakeEngine);
@Test
public void testCarCanStart() {
carWithStartableEngine.start();
Assert.assertTrue(carWithStartableEngine.isStarted);
}
…
![Page 65: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/65.jpg)
Stubs
Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed for the test.
![Page 66: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/66.jpg)
POJO Stubs
private final Engine stubEngine = new Engine() { @Override
public void stop() {}
@Override
public void start() {}
@Override
public boolean isRunning() { return false; }
};
![Page 67: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/67.jpg)
POJO Subs (cont)
private final Car car = new Car(stubEngine);
@Test
public void testCarDoesNotStartWithoutEngine() {
car.start();
Assert.assertFalse(car.isStarted);
}
![Page 68: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/68.jpg)
Spies
NSA your calls.
![Page 69: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/69.jpg)
POJO Spies
private class SpyEngine extends DieselEngine {
int startedCalledCount = 0;
@Override
public void start() {
startedCalledCount++;
super.start();
}
};
![Page 70: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/70.jpg)
POJO Spies (cont)
private final SpyEngine spyEngine = new SpyEngine();
private final Car spiedTestCar = new Car(spyEngine);
@Test
public void testCarStartStartsTheEngine() {
spiedTestCar.start();
Assert.assertEquals("Engine start is called once",
1, spyEngine.startedCalledCount);
}
![Page 71: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/71.jpg)
Mocks
Objects pre-programmed with expectations which form a specification of the calls they are expected to receive.
![Page 72: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/72.jpg)
EasyMock: Mock (too lazy)
@RunWith(EasyMockRunner.class)
public class TestMockEasyMock
extends EasyMockSupport{
@Mock
Engine mockEngine;
…
![Page 73: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/73.jpg)
EasyMock: Mock (cont)
@Test
public void testCarWithAMockedEngine() {
// Set the behavior
expect(mockEngine.isRunning()).andReturn(false);
mockEngine.start();
expect(mockEngine.isRunning()).andReturn(true);
mockEngine.stop();
replayAll();
![Page 74: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/74.jpg)
EasyMock: Mock (cont 2)
// Set a car with our mocked engine
Car testedCar = new Car(mockEngine);
// Run !
testedCar.start();
testedCar.stop();
// Verify !
verifyAll();
}
![Page 75: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/75.jpg)
POJO feels a bit ghetto ?
![Page 76: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/76.jpg)
(Some) Existing frameworks
▪ EasyMock
▪ Mockito
▪ Unitils
▪ JMockit
And Much Much more !
Proxy Based
Class remap
Strict by default
Non-Strict by default
![Page 77: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/77.jpg)
EasyMock
1. Arrange: Create the mock and setup behaviormock = createMock(Collaborator.class);mock.documentChanged("Document");expectLastCall().times(3);expect(mock.vote("Document")).andReturn((byte)-42);replay(mock);
3. ACT !classUnderTest.addDocument("Document", "content");
4. Assertverify(mock);
![Page 78: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/78.jpg)
Mockito - Behavior Check
1. ArrangeList mockedList = mock(List.class);
2. ActmockedList.add("one");mockedList.clear();
3. Assertverify(mockedList).add("one");verify(mockedList).clear();
![Page 79: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/79.jpg)
Mockito - Stubbing
1. ArrangeLinkedList mockedList = mock(LinkedList.class); when(mockedList.get(0)).thenReturn("first");when(mockedList.get(1))
.thenThrow(new RuntimeException());2. Act (examples)System.out.println(mockedList.get(0));System.out.println(mockedList.get(1));System.out.println(mockedList.get(999));
![Page 80: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/80.jpg)
Unitils (mocking)
1. Arrange (Create the mock and setup behavior)myServiceMock =
new MockObject<MyService>(MyService.class, this);myServiceMock.returns("a value").someMethod();
2. ActmyServiceMock.getMock().someMethod();
3. Assert !myServiceMock.assertNotInvoked().someMethod();
![Page 81: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/81.jpg)
JMockit - Expectations
@Testpublic void aTestMethod(@Mocked final MyCollaborator mock){ new NonStrictExpectations() {{ mock.getData(); result = "my test data"; mock.doSomething(anyInt, "some expected value", anyString);
times=1; }}; // In the replay phase, the tested method would call the "getData" and "doSomething" // methods on a "MyCollaborator" instance. ...
// In the verify phase, we may optionally verify expected invocations to // "MyCollaborator" objects. ...
}
![Page 82: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/82.jpg)
JMockit - Verification
... new Verifications() {{ // If no new instance of the mocked class should have been // created with the no-args constructor, we can verify it: new MyCollaborator(); times = 0; // Here we verify that doSomething() was executed at least once: mock.doSomething(); // Another verification, which must have occurred no more than three // times: mock.someOtherMethod(
anyBoolean, any, withInstanceOf(Xyz.class)); maxTimes = 3; }};}
![Page 83: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/83.jpg)
Conclusion
▪ Mocking helps you to create better tests▪ Mocking Framework(s) help keeping overhead low
![Page 84: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/84.jpg)
The Red Line
Goal of Testing
What to Test
Fixtures
Mocks
Assertions
![Page 85: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/85.jpg)
ASSERTIONS
![Page 86: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/86.jpg)
Assertions
What ? Verify if the result of the test is what we expected.
![Page 87: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/87.jpg)
Assertions
How ? Should be automated, no human intervention necessary No logging, System.out.println() etc. to be used Use framework(s) to achieve this.
![Page 88: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/88.jpg)
Junit assertions
TypesassertEquals, assertSame, assertTrue, assertFalse, assertNull, assertNotNull
Advantages Most often used, so best known.
![Page 89: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/89.jpg)
Junit assertions
Drawbacks▪ Not always very readable
assertEquals(expected, result) or assertEquals(result, expected)
▪ Number of assertions are limited▪ Comparing (complex) objects is hard.
impossible when object has not equals() implemented !
ConclusionIt’s ok to use them for primitive types.But there are better alternatives.
![Page 90: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/90.jpg)
Hamcrest assertions
What ?▪ Hamcrest is a framework for writing matcher objects allowing ‘match’
rules to be defined declaratively.assertThat(Object, Matcher<T>);
▪ Can easily be integrated with other frameworks like Junit, TestNG, Mockito, EasyMock, Jmock,...
![Page 91: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/91.jpg)
Hamcrest assertions
Advantages▪ Improved readability of tests
assertThat(ObjectToBeChecked, equalTo(OtherObject))
assertThat(ObjectToBeChecked, is(equalTo(OtherObject));
assertThat(collection, hasSize(2);
▪ Better failure messageassertThat(3, greaterThan(5));
Expected: a value greater than <5>
but: <3> was less than <5>
![Page 92: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/92.jpg)
Hamcrest assertions
▪ Combination of MatchersAllows to assert more precisely.
assertThat(array, not(emptyArray());
assertThat(collections, everyItem(greaterThan(10));
▪ Write your own Matcher
This can occur when you find a fragment of code that test the same set of properties over and over again and you want to bundle the fragment into a single assertion.
But be aware, there are already plenty of matchers available, make sure you are not writing existing code again.
![Page 93: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/93.jpg)
Hamcrest assertions
Example : To test if a double has a value NaN (not a number)
Test we want to write :
public void testSquareRootOfMinusOneIsNotANumber () {
assertThat(Math.sqrt(-1), is(notANumber()));
}
![Page 94: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/94.jpg)
public class IsNotANumber extends TypeSafeMatcher<Double> {
@Override
public boolean matchesSafely(Double number) {
return number.isNaN();
}
public void describeTo(Description description) {
description.appendText("not a number");
}
@Factory
public static <T> Matcher<Double> notANumber() {
return new IsNotANumber();
}
}
Hamcrest assertions
![Page 95: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/95.jpg)
Hamcrest assertions
▪ More possibilities to compare objects
It is possible to check objects that don’t have equals() implemented.
assertThat(ObjectToBeChecked, samePropertyValuesAs(OtherObject));
but not possible for objects with composition !
Better use ReflectionAssert.assertReflectionEquals of unitils !
![Page 96: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/96.jpg)
Hamcrest assertions
Drawbacks▪ Finding the right Matcher
The matchers are not set in one place. Most matchers are accessible via the Matcher class, but some are located in the CoreMatcher class, and some are in another package.
example:
hasItem() : Matcher classhasItems() : IsCollectionContaining class
![Page 97: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/97.jpg)
Other frameworks
Unitils▪ ReflectionAssert
This assertion loops over all fields in both objects and compares their values using reflection. If a field value itself is also an object, it will recursively be compared field by field using reflection. The same is true for collections, maps and arrays.
▪ Lenient assertionsAdding some levels of leniency to the ReflectionAssert checks. (order list, ignoring defaults, dates, assertLenientEquals)
▪ Property assertionsMethods to compare a specific property of two objects
assertPropertyLenientEquals("id", 1, user);
assertPropertyLenientEquals("address.street", "First street", user);
![Page 98: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/98.jpg)
Other frameworks
Fest (http://code.google.com/p/fest/)
Supports both Junit and TestNG
assertThat(collection).hasSize(6).contains(frodo, sam);
![Page 99: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/99.jpg)
Assertions
Misuse of assertions▪ Manual assertions
This practice misses out the main benefits of testing automation — the ability to continuously run the tests in the background without intervention
■ Multiple assertions
■ Redundant assertionsExtra calls to an assert method where the condition being tested is a hard coded valueassertTrue(“always true”, true)
■ Using the wrong assertionsassertTrue("Object must be null", actual == null);assertTrue("Object must not be null", actual != null);
![Page 100: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/100.jpg)
Assertions
What about void methods ?Often if a method doesn't return a value, it will have some side effect. There may be a way to verify that the side effect actually occurred as expected.
Especially exception testing should not be forgotten.
![Page 101: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/101.jpg)
Assertions
MyClass {
public void addElement(String element, List<String> elements) {
elements.add(element);
}
}
public void testAddElement() {
List<String> elements = new ArrayList();assertEquals(0, elements.size() );myClassTest.addElement(“test”, elements);assertEquals(1, elements.size() );
}
![Page 102: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/102.jpg)
Conclusion
▪ Always make sure your assertions are fully automated
▪ Junit assertions are ok for primitive types
▪ Hamcrest offers a lot of interesting matchers that allows you to assert
more precise
▪ Unitils is a better alternative when comparing objects
▪ You can use them all together !
![Page 103: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/103.jpg)
The Red Line
Goal of Testing
What to Test
Fixtures
Mocks
Assertions
![Page 104: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/104.jpg)
Question ?
![Page 105: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/105.jpg)
PRACTICAL
![Page 106: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/106.jpg)
Exercises !
github: https://github.com/pijalu/utdemo
▪ Master: Default start
▪ Branches: Different solutions with different mocking framework…
Don’t look ;-)
![Page 107: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/107.jpg)
Factoid - Model
Fact
▪ Simple POJO▪ Stores a fact▪ It’s a string
![Page 108: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/108.jpg)
Factoid - Provider
Provider interface:▪ Provides a list of fact to a client
▪ int size(): Number of facts in the provider▪ Fact getFact(index): Return a fact (0->size-1)
▪ Implementation:▪ FileFactProvider
▪ Loads facts from a file.▪ Line oriented
![Page 109: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/109.jpg)
Factoid- Service
FactService interface:▪ Returns a fact to client:
▪ Fact getAFact(): Return a fact
▪ Implementation:▪ RandomFactService:
▪ Returns a random fact using a provider▪ Uses Random▪ Builds an array to avoid repetition/ensure all facts are returned
![Page 110: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/110.jpg)
Factoid - Main
Factoid main class
▪ Loads a File with a (File)FactProvider
▪ Loads a (Random)FactService using created fact provider
▪ Calls FactService getAFact()
![Page 111: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/111.jpg)
Factoid - What to do
▪ Select the mocking framework you want▪ EasyMock to start !
▪ Check the FIXME in the existing code
▪ Fix as many as you can !▪ Be creative
▪ Look for other issues ;-)
![Page 112: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/112.jpg)
GO !
![Page 113: Unit testing - A&BP CC](https://reader036.vdocuments.mx/reader036/viewer/2022072108/5884a57e1a28ab76798b4ad9/html5/thumbnails/113.jpg)
Thanks for your attendance