Unit Testing

The “no time for testing” death spiral

Pressure

Testing

Errors

Direct

Inverse

Test-Driven Development by Example, Kent Beck

Legacy Code

Michael Feathers introduced a definition of legacy code as code without tests

Wikipedia

Unit Testing Isolation

Doubles

  • Mock
  • Stub
  • Fake
  • Dummy
  • Spy

Algunos consejos

  • Testing temprano
  • TDD
  • No sacrificar calidad por entrega
  • Probar nuevas formas*

Testing temprano

public class Dummy {

    public void dummyMethod() {
        return DummyRepository.getInstance().someMethod();
    }

}
public class Dummy {

    private repository = DummyRepository.getInstance();

    public void setRepository(DummyRepository value) {
        this.repository = value;
    }

    public void dummyMethod() {
        return this.repository.someMethod();
    }

}

TDD

No sacrificar calidad por entrega

Coverage

public class SomeClass {

    public void someMethod(int param) {
        if (param > 0 || param < 0) {
            return param * 2;
        }

        return 10;
    }

}
public class SomeClassTest {

    private SomeClass someClass = new SomeClass();

    @Test
    public void someMethodGreaterThanZero() throws Exception {
        int response = this.someClass.someMethod(10);
        assertEqual(20, response);
    }

    @Test
    public void someMethodLessThanZero() throws Exception {
        int response = this.someClass.someMethod(-10);
        assertEqual(-20, response);
    }
}

Line coverage

Branch coverage

¿JUnit?

Spock

  • Groovy
  • Retrocompatible con Java
  • BDD

JUnit vs Spock

def "should throw RestException when FECHA_NAC not exists"() {
    given:
    Variables variables = new Variables();
    variables.add(new VariableItem("FECHA_VUELTA", "10/4/2010"));
    variables.add(new VariableItem("FECHA_IDA", "10/4/2010"));
    repository.generateEstimation(_ as Variables) >> new Estimation()

    when:
    this.estimationsService.generateEstimation(variables);

    then:
    notThrown(RestException)
}
@Test(expected = RestException.class)
public void shouldThrowRestExceptionWhenFECHA_NAC_NotExists() throws Exception {
    Variables variables = new Variables();
    variables.add(new VariableItem("FECHA_VUELTA", "10/4/2010"));
    variables.add(new VariableItem("FECHA_IDA", "10/4/2010"));

    when(estimationsRepository.generateEstimation(variables)).thenReturn(new Estimation());

    this.estimationsService.generateEstimation(variables);
}

JUnit vs Spock

def "Encrypt"() {
    expect:
    CustomHash.encrypt(a) == b

    where:
    a     || b
    'abc' || 'YWJj'
    ''    || ''
    null  || ''
}
@Test(expected = RestException.class)
public void shouldThrowRestExceptionWhenFECHA_NAC_NotExists() throws Exception {
    Variables variables = new Variables();
    variables.add(new VariableItem("FECHA_VUELTA", "10/4/2010"));
    variables.add(new VariableItem("FECHA_IDA", "10/4/2010"));

    when(estimationsRepository.generateEstimation(variables)).thenReturn(new Estimation());

    this.estimationsService.generateEstimation(variables);
}

Testing

By Sebastian Diaz

Testing

  • 82