Unit testing basic

Download Unit testing basic

Post on 10-May-2015




1 download

Embed Size (px)


<ul><li>1.Unit testing(basic)November 2011</li></ul> <p>2. What is Unit TestingUnit test is a method by which individual units of source codeare tested to determine if they are fit for use.A unit is the smallest testable part of an application likemethod or class.Unit tests are written from a programmers perspective.They ensures that a particular method of a class successfullyperforms a set of operations.Unit testing drives design: developer is concerned about howclient will use the interface of the class that is under the test. 3. What is not for?Its not for testing correct inter-operation of multiplesubsystems.NOTE: It should be a stand-alone test which is not relatedto other subsystems.It should not rely on external resources like(RDBMS,LDAP etc).NOTE: Introducing dependencies on external resources ordata turns unit tests into integration tests.In many cases you cant write a unit test to reproduce bugappeared in production.NOTE: its not regression testing. with unit test you cancheck logic responsible for interaction between differentlayers. 4. The advantages of Unit Testing Ensure code continues to work as intended(only if it has agood coverage) Safe refactoring. Allows refactoring without fear to break thecode. Fewer bugs. Find some tricky bugs in logic on first stageNOTE: 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 Unit testingBig time investment. For the simple case you lose about 20%of the actual implementation, but for complicated cases you losemuch more.NOTE: If you correctly follow TDD it will going to save youtime later in long-term perspective!Design Impacts. Sometimes the high-level design is not clearat the start and evolves as you go along - this will force you tocompletely redo your test which will generate a big time lose.NOTE: postpone unit tests in this case until you haveclarified 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 A singleton gets implemented using a static method. Staticmethods are avoided by people who do unit testingbecause they cannot be mocked or stubbed.Static methods are death to unit testability ref Dont rely on external resources Do not test the GUI. 8. JUnit - Adding new test caseMark your test cases with @Test annotations.Use @Before and @After to run method before and afterevery test case. Several tests need similar objects createdbefore they can run. (See Example)Use @BeforeClass and @AfterClass to run for one timebefore and after all test cases.(Use it only to share expensivesetup)Static imports makes code more readable: (See Example)import static org.mockito.Mockito.*;import static org.junit.Assert.*;@RunWith(MockitoJUnitRunner.class) 9. JUnit test structureMake test readable. Use next pattern:// GivenCreate some objects required for testing.// WhenExecute method that is under test// ThenCheck state and verify interactionSee example 10. JUnit - Assertion1. Choose correct assert method from org.junit.Assert.*:assertNull, assertNotNull, assertTrue, assertEquals...2. Keep it simple:assertEquals(age, calculateAge(dob)); // bad practiceassertEquals(age, 25); // Best practice. Keep it simple3. Use overloaded method with argument for message:assertNull("Value must be null in case of error", value); 11. JUnit - test under constructionSometimes we need to temporarily disable a test that isunder construction. Use @Ignore annotation on methodor class to achieve it. Specify the reason why its 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 - Test Case With Exception1. Expect that exception is thrown: (See example) @Test(expected=EmailExistException.class) public voidtestExceptionIsThrown() { ... }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 codeassertEquals(exception.getCode(), 404);}3. JUnit 4.7 has @Rule ExpectedException 13. State vs Interaction testingState testing asserts properties on an objectExample: Verify that after tested method execution object hasproperties: assertEquals(2, item.getCount());Interaction testing verifies the interactions between objects.Example: Did my controller correctly call my services inspecified order? Can be used only with mocked objects.Mockito is a framework for interactions testing.Mockito is a mocking frameworkthat tastes really good! 14. Mock behavior with mocks.Mocks or mock objects simulate the behavior of complex, real(non-mock) objects and are therefore useful when a real objectis 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 towrite beautiful tests with clean &amp; simple API. 15. Why Mockito is good? with Mockito, you only stub what you need and go onhappily completing the functionality. No need to stubeverything. 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 - Mock in MockitoThis will mock all methods in MyService class and providedefault 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 - 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 usingan equals() method. 18. JUnit - Argument matching in MockitoSometimes, when extra flexibility is required then you mightuse argument matchers: when(mockedList.get(anyString())).thenReturn("element"); any(ClassName.class) Custom argument matcher:(see ArgumentMatcher)IMPORTANT: If you are using argument matchers, allarguments have to be provided: verify(mock).someMethod(anyInt(), anyString(), eq("arg")); verify(mock).someMethod(anyInt(), anyString(), "arg") -Wrong 19. JUnit - Verify behavior in MockitoOnce created, mock will remember all interactions. Then youcan 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 - Verification in orderVerification in order is flexible - you dont have to verify allinteractions one-by-one but only those that you areinterested in testing in order.//create inOrder object passing any mocks relevent for in-order verificationInOrder inOrder = inOrder(firstMock, secondMock);// make sure that firstMock was called before secondMockinOrder.verify(firstMock).add("was called first");inOrder.verify(secondMock).add("was called second"); 21. JUnit - Spy(Partial mocking) in MockitoWhen you use the Spy then the real methods are called (unlessa 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 (see Example)Eclemma plugin for eclipse: http://www.eclemma.org/#ant coverage - to generate report from console 23. Test Driven DevelopmentAfter that build project, deploy, make sure that it works.See Example 24. Unit testing is a lot like going to the gym 25. No pain, no gain* 26. Lets drink!Contact InformationEmail: yuri.anischenko@gmail.com </p>