¿Buscas nuestro logo?
Aquí te dejamos una copia, pero si necesitas más opciones o quieres conocer más, visita nuestra área de marca.
Conoce nuestra marca.¿Buscas nuestro logo?
Aquí te dejamos una copia, pero si necesitas más opciones o quieres conocer más, visita nuestra área de marca.
Conoce nuestra marca.dev
Fátima Casaú 05/04/2017 Cargando comentarios…
Después de la primera parte de Testing orientado a BDD con Spock, en el que vimos cómo escribir especificaciones BDD para pruebas con Spock, en este post vamos a ver algunas utilidades más avanzadas que tenemos a nuestra disposición: cómo hacer mocking y stubbing, cómo testear excepciones o cómo utilizar algunas extensiones que nos pueden ser de gran ayuda.
También veremos cómo sacar unos estupendos informes de tests que nos serán útiles tanto para el equipo como para el cliente.
Seguro que, después de leer el primer post, te has preguntado cómo simular el comportamiento de algunos de tus servicios o funcionalidades sin necesidad de implementarlos o ejecutarlos. Para ello, Spock nos da soporte para hacer mocking y stubbing. Veamos en qué consiste cada uno.
Cuando hacemos ‘mocking’ conseguimos simular el comportamiento de una clase y las interacciones con otros colaboradores.
Cuando hacemos ‘stubbing’ podemos especificar cómo queremos que se comporten los métodos de una clase.
Si vemos el ejemplo, al hacer mocking de ‘NotificacionService’ lo estamos simulando, sin necesidad de levantar el contexto de la aplicación. Por otro lado, al hacer stubbing de ‘CustomerRepositoy’ no solo lo estamos simulando, sino que estamos especificando qué resultado queremos que devuelva su método ‘save’ (en esta caso, que devuelva ‘true’) sin especificar qué parámetros le vamos a pasar.
Por tanto, en este escenario, el resultado de llamar al método ‘CustomerService.registerCustomer()’ con unos datos cualquiera es que se va a invocar al método ‘NotificationService.sendWelcomeMessage()’ devolviendo el mensaje ‘Hi, welcome!’.
groovy
interface NotificationService {
def sendWelcomeMessage(Customer customer, String message);
def sendErrorMessage(Customer customer, String message);
}
NotificationService.groovy
@RepositoryRestResource(collectionResourceRel = "customer", path = "customer")
public interface CustomerRepository extends CrudRepository<Customer, Long> {
List<Customer> findByName(String name)
// Method save --> implicit method because
// CustomerRepository extends of CrudRepository
}
CustomerRepository.groovy
void 'Send welcome notificacion when customer is created'() {
setup:
// Mocking
def mockedNotificationService = Mock(NotificationService)
// Stubbing
def stubbedCustomerRepository = Stub(CustomerRepository){
save(_) >> true // customerRepository.save() method was ok
}
def customerService = new CustomerService(mockedNotificationService,stubbedCustomerRepository)
When: 'A costumer is created correctly'
customerService.registerCustomer('CustomerName', 'CustomerSurname')
then: 'A welcome notification is sent'
1 * mockedNotificationService.sendWelcomeMessage(_, "Hi, welcome!") // One call to this method
and: 'An error message is not sent'
0 * mockedNotificationService.sendErrorMessage(_, _) // No calls to this method
}
MockingAndStubbingSpec.groovy
class CustomerService {
private NotificationService notificationService
private CustomerRepository customerRepository
public CustomerService(NotificationService notificationService,CustomerRepository customerRepository) {
this.notificationService = notificationService
this.customerRepository = customerRepository
}
void registerCustomer(String name, String lastName) {
Customer customer = new Customer(name:name, lastName:lastName)
if(customerRepository.save(customer))
notificationService.sendWelcomeMessage(customer, "Hi, welcome!")
else {
notificationService.sendErrorMessage(customer, "Oops, an error has ocurred!")
}
}
}
CustomerService.groovy
Con Spock también podemos comprobar en nuestros test si se lanzan excepciones:
def 'Throw NullPointerException'() {
given: 'a null object'
Customer customer = null
when: 'try to access to the object'
customer.name
then:'throw a nullpointerexception'
thrown NullPointerException
}
Además de anotaciones como las ya vistas en el post anteior (@Shared, @Unroll), veamos ahora algunas otras disponibles que nos proporcionarán utilidades extra a la hora de implementar nuestros tests.
Podemos utilizar estas anotaciones para añadir un título y una explicación a nuestros tests, como por ejemplo, la descripción de la historia de usuario.
@Narrative("""
As a user
I want to search customers by name
to find them quickly
""")
@Title("""This is easy
to read
_______________________
""")
class Example9_SearchCustomerUnitSpec extends Specification { … }
Podemos utilizar esta extensión para enlazar la ‘issue’, ‘tarea’, ‘user story’ o elemento al que haga referencia nuestro test.
groovy
""")
@Issue("https://github.com/spockframework/spock/issues/684")
class Example9_SearchCustomerUnitSpec extends Specification{...}
Estas etiquetas nos sirven respectivamente para: ignorar un test, ignorar el resto (menos el anotado) o ignorar bajo una condición:
groovy
@IgnoreIf({ isFriendsCharacter("Rachel") })
void 'run if is a friend character'() {
expect:
true
}
// helper methods
static boolean isFriendsCharacter(String name) {
name in ['Rachel', 'Monica', 'Phoebe', 'Joey', 'Chandler', 'Ross']
}
Cuando necesitamos que se cumpla una condición:
groovy
@Requires({ OperatingSystem.current.macOs })
void 'only run on MacOS'() {
expect:
println 'MacOS'
true
}
Una clase de test anotada con @Stepwise asegura que el orden de ejecución de los test es tal y como se ha declarado. Además, si uno de los tests de la clase falla, el resto no se ejecuta. Si tenemos tests anotados con alguno de los @Ignore… se ignorarán tal y como se hayan declarado.
Sirve para que los tests de una clase o un test en concreto fallen si se excede de un tiempo determinado (por defecto en milisegundos aunque podemos especificar las unidades):
groovy
@Timeout(value = 100, unit = TimeUnit.MILLISECONDS)
Encontramos más información en ‘Extensions’.
Como introducía al principio de este post, Spock, por defecto, nos proporciona unos informes en html o xml donde, por cada ejecución, se muestra el resultado de dichos tests. Pero, además, está disponible la librería ‘Spock Reports Extension’ que da un paso más en la generación de dichos informes, proporcionando más información y permitiendo customización.
Si, por ejemplo, usas Gradle, solo tienes que añadir esta librería a tus dependencias:
groovy
testCompile( 'com.athaydes:spock-reports:1.2.13' )
Como resultado, tendremos unos informes con este aspecto:
Por último, puedes encontrar toda la documentación y recursos del framework en la web oficial de Spock. Espero que después de haber leído el primer post y ahora éste, te animes a implementar las pruebas de tus proyectos con este framework y que aproveches la ocasión para iniciarte con Groovy como lenguaje de programación.
Los comentarios serán moderados. Serán visibles si aportan un argumento constructivo. Si no estás de acuerdo con algún punto, por favor, muestra tus opiniones de manera educada.
Cuéntanos qué te parece.