Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Elegant?? Unit Testing

Elegant?? Unit Testing

In this session we will learn the basics of Unit Testing and its importance. We will define what a Unit Test is, what type of Unit Tests there are and then talk about Test Doubles. Finally, we will focus on how to write new tests and improve existing ones by reviewing some Android Github projects.

Video (Spanish): https://upclose.me/Aracem/6121

Pablo Guardiola

February 23, 2015
Tweet

More Decks by Pablo Guardiola

Other Decks in Programming

Transcript

  1. 4 rules of simple design 1. Runs all the Tests

    2. Reveals all the intention 3. No duplication 4. Fewest number of classes or methods
  2. Testing motivators Validate the System Code Coverage Enable Refactoring Document

    the Behaviour of the System Your Manager Told You To Test Driven Development Customer Acceptance Ping-Pong Pair Programming
  3. Unit Test SOLITARY SOCIABLE 1. Never cross boundaries 2.The Class

    Under Test should be the only concrete class found in a test
  4. Dummy public class DummyAuthorizer implements Authorizer {
 @Override
 public Boolean

    authorize(String username, String password) {
 return null;
 }
 }
  5. Stub public class AcceptingAuthorizerStub implements Authorizer {
 @Override
 public Boolean

    authorize(String username, String password) {
 return true;
 }
 }
  6. Spy public class AcceptingAuthorizerSpy implements Authorizer {
 public boolean authorizeWasCalled

    = false;
 
 public Boolean authorize(String username, String password) {
 authorizeWasCalled = true;
 return true;
 }
 }
  7. Mock public class AcceptingAuthorizerVerificationMock implements Authorizer {
 public boolean authorizeWasCalled

    = false;
 
 public Boolean authorize(String username, String password) {
 authorizeWasCalled = true;
 return true;
 }
 
 public boolean verify() {
 return authorizeWasCalled;
 }
 }
  8. Fake public class AcceptingAuthorizerFake implements Authorizer {
 public Boolean authorize(String

    username, String password) {
 return username.equals("Bob");
 }
 }
  9. ANDROID Unit Testing Java Module MVP CLEAN Architecture AS 1.1

    + Android Gradle Plugin MVVM KOR Rosie?
  10. public class FooTest {
 
 @Test
 public void sampleTest() throws

    Exception {
 assertEquals(expected, actual);
 }
 } JUnit
  11. Material Movies @Test
 public void obtainFiftyShadesOfGreyMovie() throws Exception {
 MediaDataSource

    inMemoryData = new InMemoryMovieSource();
 GetMoviesInMemoryUsecaseController popularMovies = new GetMoviesInMemoryUsecaseController(GetMoviesUsecase.TV_MOVIES, inMemoryData);
 
 popularMovies.execute();
 
 assertEquals("Fifty Shades of Grey", ((InMemoryMovieSource) popularMovies.obtainMediaData()).obtainInMemoryMovies().get(3).getTitle());
 }
  12. Material Movies @Test
 public void checkIfPopularMoviesIsCalled() throws Exception {
 GetMoviesUsecase

    popularMovies = new GetMoviesUsecaseController(GetMoviesUsecase.TV_MOVIES);
 GetMoviesUsecase spy = Mockito.spy(popularMovies);
 
 spy.execute();
 
 verify(spy).getPopularMovies();
 }
  13. One Assertion Per Test (State Verification) @Test public void shouldCreateVerboseTraceFromStringTrace()

    throws Exception {
 Trace trace = Trace.fromString(VERBOSE_TRACE);
 
 assertEquals(TraceLevel.VERBOSE, trace.getLevel());
 assertEquals(ANY_TRACE_DATE + " " + VERBOSE_TRACE_MESSAGE, trace.getMessage());
 }
  14. ANNOYING to have to look at the STACKTRACE to know

    what’s FAILING Have NO INFORMATION about REMAINING TESTS
  15. One Assertion Per Test (Behavior Verification) @Test public void shouldNotUpdateFilterIfPresenterIsNotInitialized()

    {
 presenter.updateFilter(ANY_FILTER);
 
 verify(lynx, never()).setConfig(any(LynxConfig.class));
 verify(lynx, never()).restart();
 }
  16. 1. If your test has an assertion, do not add

    any mock verifications 2. If your test verifies a mock, do not add any assertions 3. At most, 1 assertion per test 4. At most, 1 mock verification per test Rule of thumb
  17. Expect Literals @Test
 public void testSaveAllNextLevel() throws Exception {
 doReturn(Boolean.TRUE).when(repository).hasNextLevel();


    
 assertEquals(elements.size(), repository.saveAll(elements).size());
 verify(nextLevel, times(1)).saveAll(anyCollection());
 }
  18. Inline Setup @Before
 public void setUp() throws Exception {
 initMocks(this);


    
 elements.add(mockedElement1);
 elements.add(mockedElement2);
 elements.add(mockedElement3);
 
 ids.add(EXPECTED_FIRST_ID);
 ids.add(EXPECTED_SECOND_ID);
 ids.add(EXPECTED_THIRD_ID);
 
 repository = new BaseFastRepositoryImpl(currentLevel, null);
 }
  19. Separating The Solitary From The Sociable 1. Can be slow

    and nondeterministic 2. Are more susceptible to cascading failures Sociable Unit Tests
  20. Should we even bother writing Unit Tests? “The key is

    to test the areas that you are most worried about going wrong. That way you get the most benefit for your testing effort.” Martin Fowler, Refactoring
  21. Extreme Programming Explained: Embrace Change, Kent Beck, AddisonWesley. Working Effectively

    with Unit Tests by Jay Fields Bibliography Mocks Aren’t Stubs (www.martinfowler.com/articles/mocksArentStubs.html) The Little Mocker (blog.8thlight.com/uncle-bob/2014/05/14/TheLittleMocker.html) https://github.com/saulmm/Material-Movies https://github.com/pedrovgs/Lynx https://github.com/Sefford/kor Clean Code: A handbook of Agile Software Craftsmanship, Robert C. Martin Software Craftsmanship by Sandro Mancuso