Probando la interfaz o la implementación

Hoy mientras escribía unas pruebas unitarias para los métodos de una interfaz me preguntaba que es lo que se debe probar, la realización de una interfaz o una implementación de esa interfaz.

Esto es:

Prueba de la realización de una interfaz:


public class Data {
}

public interface DataProvider {

/**
* @param encodedData
* @return
* @should extract data in a platform specific way
*/
Data extractData(String encodedData);

}

 


public class DataProviderTest {
/**
* @verifies extract data in a platform specific way
* @see DataProvider#extractData(String)
*/
@org.junit.Test
public void extractData_shouldExtractDataInAPlatformSpecificWay() throws Exception {
//TODO auto-generated
Assert.fail("Not yet implemented");
}
}

Prueba de la implementación


public interface DataProvider {

/**
* @param encodedData
* @return
* @should extract data in a platform specific way
*/
Data extractData(String encodedData);

}

 


public class DataProvideImpl1 implements DataProvider {

/**
* @param encodedData
* @return
* @should extract data in a platform specific way
*/
@Override
public Data extractData(String encodedData) {
return null;

}

/**
* @should do something impl specific
*/
void implementationSpeficMethod() {

}
}

 


public class DataProvideImpl1Test {

/**
* @verifies extract data in a platform specific way
* @see DataProvideImpl1#extractData(String)
*/
@org.junit.Test
public void extractData_shouldExtractDataInAPlatformSpecificWay() throws Exception {
//TODO auto-generated
Assert.fail("Not yet implemented");
}
/**
* @verifies do something impl specific
* @see DataProvideImpl1#implementationSpeficMethod()
*/
@org.junit.Test
public void implementationSpeficMethod_shouldDoSomethingImplSpecific() throws Exception {
//TODO auto-generated
Assert.fail("Not yet implemented");
}

}

Y pues dado que la aplicación debería girar en torno a los servicios (métodos) provistos por las interfaces, y como recomienda la metodología TDD al sugerir que debemos programar concentrados en el cumplimiento de las interfaces (realizaciones) , pues parece bastante claro que nuestro principal y derepente único interés debería ser hacer que se cumpla el contrato de cada uno de los métodos de las interfaces,por lo cual es exactamente eso lo que deberían probar nuestros método y no tendrían por qué hacer algo como (ahora mismo no se me ocurre una excepción a esta regla):

</pre>
/**
* @verifies do something impl specific
* @see DataProvideImpl1#implementationSpeficMethod()
*/
@org.junit.Test
public void implementationSpeficMethod_shouldDoSomethingImplSpecific() throws Exception {
//TODO auto-generated
Assert.fail("Not yet implemented");
}
<pre>

Pero si es así surge un problema, qué sucede cuando tenemos más de una implementación, de qué manera nombramos a la clase de pruebas, está claro que no podría ser InterfazBajoPruebaTest, debido a que hay más de una implementación y el código en la clase InterfazBajoPruebaTest solo debería probar código para una implementación.


public interface DataProvider {

/**
* @param encodedData
* @return
* @should extract data in a platform specific way
*/
Data extractData(String encodedData);

}

public class DataProvideImpl1 implements DataProvider {

/**
* @param encodedData
* @return
* @should extract data in a platform specific way
*/
@Override
public Data extractData(String encodedData) {
return null;

}

/**
* @should do something impl specific
*/
void implementationSpeficMethod() {

}
}

public class DataProviderImpl2 implements DataProvider{

/**
* @param encodedData
* @return
* @should extract data in a platform specific way
*/
@Override
public Data extractData(String encodedData) {
return null;
}
}

public class DataProviderTest {
/**
* @verifies extract data in a platform specific way
* @see DataProvider#extractData(String)
*/
@org.junit.Test
public void extractData_shouldExtractDataInAPlatformSpecificWay() throws Exception {
//TODO auto-generated
Assert.fail("Not yet implemented");
}
}

Por lo tanto sugiero como solución a este problema. Utilizar el nombre de las implementaciones para las clases de prueba pero solo los métodos de la interfaz implementada para la creación de los métodos de pruebas, esto es, no se deberían probar los métodos que no sean parte del contrato establecido por la interfaz.

public interface DataProvider {

/**
* @param encodedData
* @return
* @should extract data in a platform specific way
*/
Data extractData(String encodedData);

}

public class DataProvideImpl1 implements DataProvider {

/**
* @param encodedData
* @return
* @should extract data in a platform specific way
*/
@Override
public Data extractData(String encodedData) {
return null;

}

/**
* do something impl specific (not tested)
*/
void implementationSpeficMethod() {

}
}

public class DataProvideImpl1Test {

/**
* @verifies extract data in a platform specific way
* @see DataProvideImpl1#extractData(String)
*/
@org.junit.Test
public void extractData_shouldExtractDataInAPlatformSpecificWay() throws Exception {
//TODO auto-generated
Assert.fail("Not yet implemented");
}

}

public class DataProviderImpl2 implements DataProvider{

/**
* @param encodedData
* @return
* @should extract data in a platform specific way
*/
@Override
public Data extractData(String encodedData) {
return null;
}
}
public class DataProviderImpl2Test {
/**
* @verifies extract data in a platform specific way
* @see DataProviderImpl2#extractData(String)
*/
@org.junit.Test
public void extractData_shouldExtractDataInAPlatformSpecificWay() throws Exception {
//TODO auto-generated
Assert.fail("Not yet implemented");
}
}

Leave a Reply

Your email address will not be published. Required fields are marked *