Unit testing

    (basic)
  November 2011
What is Unit Testing

Unit test is a method by which individual units of source code
are tested to determine if they are fit for use.
A unit is the smallest testable part of an application like
method or class.

Unit tests are written from a programmer’s perspective.
They ensures that a particular method of a class successfully
performs a set of operations.

Unit testing drives design: developer is concerned about how
client will use the interface of the class that is under the test.
What is not for?
It's not for testing correct inter-operation of multiple
subsystems.
NOTE: It should be a stand-alone test which is not related
to other subsystems.

It should not rely on external resources like(RDBMS,LDAP etc).
NOTE: Introducing dependencies on external resources or
data turns unit tests into integration tests.

In many cases you can't write a unit test to reproduce bug
appeared in production.
NOTE: it's not regression testing. with unit test you can
check logic responsible for interaction between different
layers.
The advantages of Unit Testing
● Ensure code continues to work as intended(only if it has a
  good coverage)

● Safe refactoring. Allows refactoring without fear to break the
  code.

● Fewer bugs. Find some tricky bugs in logic on first stage
  NOTE: tricky unit test scenarios may prevent many bugs.

● Developer concentrates more on the code and design.
  NOTE: less build/deploy cycles to see some progress.
  green bar shows you the progress

● Documentation
Disadvantages of Unit testing
Big time investment. For the simple case you lose about 20%
of the actual implementation, but for complicated cases you lose
much more.
NOTE: If you correctly follow TDD it will going to save you
time later in long-term perspective!

Design Impacts. Sometimes the high-level design is not clear
at the start and evolves as you go along - this will force you to
completely redo your test which will generate a big time lose.
NOTE: postpone unit tests in this case until you have
clarified high-level design.
Best Practices
 ● Make sure your tests test one thing and one thing only.
 ● Readability is important for tests. (see Example)
 ● Each unit test should be independent from the other.
 ● Separate you concerns. Extract layers to improve the
   design. (see Example with DAO layer)
 ● Mock behavior with mocks to concentrate on test
   scenario.
 ● Test Coverage(Check coverage during testing)
 ● Tests should run automatically to provide continuous
   feedback.
   Keep the bar green to keep the code clean!
Bad practices
● A singleton gets implemented using a static method. Static
  methods are avoided by people who do unit testing
  because they cannot be mocked or stubbed.
  Static methods are death to unit testability ref

● Don't rely on external resources

● Do not test the GUI.
JUnit - Adding new test case
Mark your test cases with @Test annotations.

Use @Before and @After to run method before and after
every test case. Several tests need similar objects created
before they can run. (See Example)

Use @BeforeClass and @AfterClass to run for one time
before and after all test cases.(Use it only to share expensive
setup)

Static imports makes code more readable: (See Example)
import static org.mockito.Mockito.*;
import static org.junit.Assert.*;

@RunWith(MockitoJUnitRunner.class)
JUnit test structure
Make test readable. Use next pattern:

// Given
Create some objects required for testing.

// When
Execute method that is under test

// Then
Check state and verify interaction

See example
JUnit - Assertion
1. Choose correct assert method from org.junit.Assert.*:
assertNull, assertNotNull, assertTrue, assertEquals...

2. Keep it simple:
assertEquals(age, calculateAge(dob)); // bad practice
assertEquals(age, 25); // Best practice. Keep it simple

3. Use overloaded method with argument for message:
assertNull("Value must be null in case of error", value);
JUnit - test under construction
Sometimes we need to temporarily disable a test that is
under construction. Use @Ignore annotation on method
or class to achieve it. Specify the reason why it's ignored.

@Ignore("Enable when TASK-2 is implemented")
public class MyClassTest {
  @Test public void testThat1() { ... }
  @Test public void testThat2() { ... }
}

public class MyClassTest {
  @Ignore("Gotta go now! will fix it later.")
  @Test void testThat1() { ... }
}
JUnit - Test Case With Exception
1. Expect that exception is thrown: (See example) @Test
(expected=EmailExistException.class) public void
testExceptionIsThrown() { ... }
2. More flexible old school way:
try { // execute method under the test customerService.add
(customer);
fail("exception must be thrown");
} catch (ServiceException exception) {
// state assertion: check error code
assertEquals(exception.getCode(), 404);
}
3. JUnit 4.7 has @Rule ExpectedException
State vs Interaction testing
State testing asserts properties on an object
Example: Verify that after tested method execution object has
properties: assertEquals(2, item.getCount());

Interaction testing verifies the interactions between objects.
Example: Did my controller correctly call my services in
specified order? Can be used only with mocked objects.

Mockito is a framework for interactions testing.

Mockito is a mocking framework
that tastes really good!
Mock behavior with mocks.
Mocks or mock objects simulate the behavior of complex, real
(non-mock) objects and are therefore useful when a real object
is impractical or impossible to incorporate into a unit test.

 They provide:
 ● Default values unless stubbed
 ● Can help verify interactions, order of interaction, method
   parameters etc.

Mockito is a Java based mocking framework that allows you to
write beautiful tests with clean & simple API.
Why Mockito is good?

● with Mockito, you only stub what you need and go on
  happily completing the functionality. No need to stub
  everything.

● simple and clean syntax

● all required documentation can be found in javadocs to org.
  mockito.Mockito.

● Has an ability to create partial mocks.

● It tastes really good
JUnit - Mock in Mockito
This will mock all methods in MyService class and provide
default values:

 1. @Mock MyService myService;
    All classes with @Mock annotation will be injected to
    @InjectMocks class by type automatically when using
    @RunWith(MockitoJUnitRunner.class).

 2. You can mock and inject services manually:
    MyService myService = mock(MyService.class);
    ServiceUnderTest service = new ServiceUnderTest();
    service.setMyService(myService);
You can mock concrete classes, not only interfaces!
JUnit - Stubbing in Mockito
 Stubbing is adding canned response to Mock object methods.

Examples:
 ● method stubbing:
   when(mockService.someMethod(”value”))
     .thenReturn(”someValue”);
 ● stubbing method with exception:
   when(mockService.someMethod("value"))
     .thenThrow(new MyException("Error"));
   or stubbing void method with exception:
   doThrow(new MyException(”Error”)
     .when(mockService).someMethod("value");

Mockito verifies argument values in natural java style: by using
an equals() method.
JUnit - Argument matching in Mockito

Sometimes, when extra flexibility is required then you might
use argument matchers:
 ● when(mockedList.get(anyString())).thenReturn("element");
 ● any(ClassName.class)
 ● Custom argument matcher:(see ArgumentMatcher)

IMPORTANT: If you are using argument matchers, all
arguments have to be provided:
 verify(mock).someMethod(anyInt(), anyString(), eq("arg"));
 verify(mock).someMethod(anyInt(), anyString(), "arg") -
Wrong
JUnit - Verify behavior in Mockito
Once created, mock will remember all interactions. Then you
can selectively verify whatever interaction you are interested in:

 ● verify(mockService).someMethod("someArgs");
 ● verify(mockService, times(2)).someMethod("someArgs");
 ● verify(mockService, never()).someMethod("someArgs");
   NOTE: never() is an alias to times(0)
 ● atLeastOnce()
 ● atLeast(2)
 ● atMost(5)
 ● verifyZeroInteractions(mockService)
 ● verifyNoMoreInteractions(mockService)
JUnit - Verification in order
Verification in order is flexible - you don't have to verify all
interactions one-by-one but only those that you are
interested in testing in order.

//create inOrder object passing any mocks relevent for in-order verification
InOrder inOrder = inOrder(firstMock, secondMock);

// make sure that firstMock was called before secondMock
inOrder.verify(firstMock).add("was called first");
inOrder.verify(secondMock).add("was called second");
JUnit - Spy(Partial mocking) in Mockito
When you use the Spy then the real methods are called (unless
a method was stubbed).
  ● Calls real methods unless the method is stubbed.
  ● Use of too much spy is potential code smell.

   MyService myService = new MyService();
   MyService spy = spy(myService);
   //optionally, you can stub out some methods when(spy.
   someMethod()).thenReturn(val);
   //real method logic will be executed
   spy.realMethod();

   See Example
Test Coverage (see Example)
Eclemma plugin for eclipse: http://www.eclemma.org/




#ant coverage - to generate report from console
Test Driven Development




After that build project, deploy, make sure that it works.
See Example
Unit testing is a lot like going to the gym
No pain, no gain

*
Let's drink!


Contact Information
Email: yuri.anischenko@gmail.com

Unit testing basic

  • 1.
    Unit testing (basic) November 2011
  • 2.
    What is UnitTesting Unit test is a method by which individual units of source code are tested to determine if they are fit for use. A unit is the smallest testable part of an application like method or class. Unit tests are written from a programmer’s perspective. They ensures that a particular method of a class successfully performs a set of operations. Unit testing drives design: developer is concerned about how client will use the interface of the class that is under the test.
  • 3.
    What is notfor? It's not for testing correct inter-operation of multiple subsystems. NOTE: It should be a stand-alone test which is not related to other subsystems. It should not rely on external resources like(RDBMS,LDAP etc). NOTE: Introducing dependencies on external resources or data turns unit tests into integration tests. In many cases you can't write a unit test to reproduce bug appeared in production. NOTE: it's not regression testing. with unit test you can check logic responsible for interaction between different layers.
  • 4.
    The advantages ofUnit Testing ● Ensure code continues to work as intended(only if it has a good coverage) ● Safe refactoring. Allows refactoring without fear to break the code. ● Fewer bugs. Find some tricky bugs in logic on first stage NOTE: tricky unit test scenarios may prevent many bugs. ● Developer concentrates more on the code and design. NOTE: less build/deploy cycles to see some progress. green bar shows you the progress ● Documentation
  • 5.
    Disadvantages of Unittesting Big time investment. For the simple case you lose about 20% of the actual implementation, but for complicated cases you lose much more. NOTE: If you correctly follow TDD it will going to save you time later in long-term perspective! Design Impacts. Sometimes the high-level design is not clear at the start and evolves as you go along - this will force you to completely redo your test which will generate a big time lose. NOTE: postpone unit tests in this case until you have clarified high-level design.
  • 6.
    Best Practices ●Make sure your tests test one thing and one thing only. ● Readability is important for tests. (see Example) ● Each unit test should be independent from the other. ● Separate you concerns. Extract layers to improve the design. (see Example with DAO layer) ● Mock behavior with mocks to concentrate on test scenario. ● Test Coverage(Check coverage during testing) ● Tests should run automatically to provide continuous feedback. Keep the bar green to keep the code clean!
  • 7.
    Bad practices ● Asingleton gets implemented using a static method. Static methods are avoided by people who do unit testing because they cannot be mocked or stubbed. Static methods are death to unit testability ref ● Don't rely on external resources ● Do not test the GUI.
  • 8.
    JUnit - Addingnew test case Mark your test cases with @Test annotations. Use @Before and @After to run method before and after every test case. Several tests need similar objects created before they can run. (See Example) Use @BeforeClass and @AfterClass to run for one time before and after all test cases.(Use it only to share expensive setup) Static imports makes code more readable: (See Example) import static org.mockito.Mockito.*; import static org.junit.Assert.*; @RunWith(MockitoJUnitRunner.class)
  • 9.
    JUnit test structure Maketest readable. Use next pattern: // Given Create some objects required for testing. // When Execute method that is under test // Then Check state and verify interaction See example
  • 10.
    JUnit - Assertion 1.Choose correct assert method from org.junit.Assert.*: assertNull, assertNotNull, assertTrue, assertEquals... 2. Keep it simple: assertEquals(age, calculateAge(dob)); // bad practice assertEquals(age, 25); // Best practice. Keep it simple 3. Use overloaded method with argument for message: assertNull("Value must be null in case of error", value);
  • 11.
    JUnit - testunder construction Sometimes we need to temporarily disable a test that is under construction. Use @Ignore annotation on method or class to achieve it. Specify the reason why it's ignored. @Ignore("Enable when TASK-2 is implemented") public class MyClassTest { @Test public void testThat1() { ... } @Test public void testThat2() { ... } } public class MyClassTest { @Ignore("Gotta go now! will fix it later.") @Test void testThat1() { ... } }
  • 12.
    JUnit - TestCase With Exception 1. Expect that exception is thrown: (See example) @Test (expected=EmailExistException.class) public void testExceptionIsThrown() { ... } 2. More flexible old school way: try { // execute method under the test customerService.add (customer); fail("exception must be thrown"); } catch (ServiceException exception) { // state assertion: check error code assertEquals(exception.getCode(), 404); } 3. JUnit 4.7 has @Rule ExpectedException
  • 13.
    State vs Interactiontesting State testing asserts properties on an object Example: Verify that after tested method execution object has properties: assertEquals(2, item.getCount()); Interaction testing verifies the interactions between objects. Example: Did my controller correctly call my services in specified order? Can be used only with mocked objects. Mockito is a framework for interactions testing. Mockito is a mocking framework that tastes really good!
  • 14.
    Mock behavior withmocks. Mocks or mock objects simulate the behavior of complex, real (non-mock) objects and are therefore useful when a real object is impractical or impossible to incorporate into a unit test. They provide: ● Default values unless stubbed ● Can help verify interactions, order of interaction, method parameters etc. Mockito is a Java based mocking framework that allows you to write beautiful tests with clean & simple API.
  • 15.
    Why Mockito isgood? ● with Mockito, you only stub what you need and go on happily completing the functionality. No need to stub everything. ● simple and clean syntax ● all required documentation can be found in javadocs to org. mockito.Mockito. ● Has an ability to create partial mocks. ● It tastes really good
  • 16.
    JUnit - Mockin Mockito This will mock all methods in MyService class and provide default values: 1. @Mock MyService myService; All classes with @Mock annotation will be injected to @InjectMocks class by type automatically when using @RunWith(MockitoJUnitRunner.class). 2. You can mock and inject services manually: MyService myService = mock(MyService.class); ServiceUnderTest service = new ServiceUnderTest(); service.setMyService(myService); You can mock concrete classes, not only interfaces!
  • 17.
    JUnit - Stubbingin Mockito Stubbing is adding canned response to Mock object methods. Examples: ● method stubbing: when(mockService.someMethod(”value”)) .thenReturn(”someValue”); ● stubbing method with exception: when(mockService.someMethod("value")) .thenThrow(new MyException("Error")); or stubbing void method with exception: doThrow(new MyException(”Error”) .when(mockService).someMethod("value"); Mockito verifies argument values in natural java style: by using an equals() method.
  • 18.
    JUnit - Argumentmatching in Mockito Sometimes, when extra flexibility is required then you might use argument matchers: ● when(mockedList.get(anyString())).thenReturn("element"); ● any(ClassName.class) ● Custom argument matcher:(see ArgumentMatcher) IMPORTANT: If you are using argument matchers, all arguments have to be provided: verify(mock).someMethod(anyInt(), anyString(), eq("arg")); verify(mock).someMethod(anyInt(), anyString(), "arg") - Wrong
  • 19.
    JUnit - Verifybehavior in Mockito Once created, mock will remember all interactions. Then you can selectively verify whatever interaction you are interested in: ● verify(mockService).someMethod("someArgs"); ● verify(mockService, times(2)).someMethod("someArgs"); ● verify(mockService, never()).someMethod("someArgs"); NOTE: never() is an alias to times(0) ● atLeastOnce() ● atLeast(2) ● atMost(5) ● verifyZeroInteractions(mockService) ● verifyNoMoreInteractions(mockService)
  • 20.
    JUnit - Verificationin order Verification in order is flexible - you don't have to verify all interactions one-by-one but only those that you are interested in testing in order. //create inOrder object passing any mocks relevent for in-order verification InOrder inOrder = inOrder(firstMock, secondMock); // make sure that firstMock was called before secondMock inOrder.verify(firstMock).add("was called first"); inOrder.verify(secondMock).add("was called second");
  • 21.
    JUnit - Spy(Partialmocking) in Mockito When you use the Spy then the real methods are called (unless a method was stubbed). ● Calls real methods unless the method is stubbed. ● Use of too much spy is potential code smell. MyService myService = new MyService(); MyService spy = spy(myService); //optionally, you can stub out some methods when(spy. someMethod()).thenReturn(val); //real method logic will be executed spy.realMethod(); See Example
  • 22.
    Test Coverage (seeExample) Eclemma plugin for eclipse: http://www.eclemma.org/ #ant coverage - to generate report from console
  • 23.
    Test Driven Development Afterthat build project, deploy, make sure that it works. See Example
  • 24.
    Unit testing isa lot like going to the gym
  • 25.
  • 26.
    Let's drink! Contact Information Email:yuri.anischenko@gmail.com