2015-03-27 10 views
6

Per prima cosa, nel caso in cui vi sia un modo più semplice per risolvere questo problema, ecco una descrizione di ciò che sto cercando di realizzare. Voglio annotare i miei metodi di prova con un'annotazione KnownIssue (che estende AbstractAnnotationDrivenExtension) che accetta un ID difetto come parametro e controlla lo stato del difetto prima dell'esecuzione dei test. Se il difetto è corretto, continuerà l'esecuzione, se non è fisso, voglio che ignori il test, ma se è chiuso o cancellato, voglio indurre un errore di test con la registrazione che indica che il test deve essere rimosso o aggiornato e l'annotazione rimossa dal momento che il difetto è ora chiuso o cancellato.Come posso ottenere a spock l'esecuzione di un metodo diverso in fase di esecuzione utilizzando un'estensione annotazione?

Ho tutto funzionante fino all'induzione di un errore di test. Quello che ho provato non funziona:

  • Lanciare un'eccezione nel metodo visitFeatureAnnotazione, che causa un errore che causa non tutti i test da quel momento in poi non eseguiti.
  • Creazione di una classe che estende Spec e che include un metodo di prova che registra un messaggio e non riesce, quindi ha provato a utilizzare feature.featureMethod.setReflection() per impostare il metodo da eseguire sull'altro metodo. In questo caso, ottengo un java.lang.IllegalArgumentException: object non è un'istanza di dichiarare la classe
  • Ho quindi provato a utilizzare ExpandoMetaClass per aggiungere un metodo direttamente a dichiaringClass e puntare feature.featureMethod.setReflection per puntare ad esso, ma ottengo ancora la stessa IllegalArgumentException.

Ecco quello che ho dentro del mio metodo visitFeatureAnnotation per il mio ultimo tentativo:

def myMetaClass = feature.getFeatureMethod().getReflection().declaringClass.metaClass 
myMetaClass.KnownIssueMethod = { -> return false } 
feature.featureMethod.setReflection(myMetaClass.methods[0].getDoCall().getCachedMethod()); 

Tutte le altre idee su come potrei fare questo, e sia indurre un fallimento del test, o sostituire il metodo con un altro che fallirà?

risposta

1

Ok ... Alla fine ho trovato una soluzione. Ecco cosa ho lavorato. All'interno del metodo visitFeatureAnnotation aggiungo un CauseFailureInterceptor che ho creato.

Ecco il sorgente completo nel caso in cui qualcuno è interessato, solo richiede di estendere la KnownIssueExtension e implementare il metodo astratto getDefectStatus:

public abstract class KnownIssueExtension extends AbstractAnnotationDrivenExtension<KnownIssue> { 
    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(KnownIssueExtension.class) 
    public void visitFeatureAnnotation(KnownIssue knownIssue, FeatureInfo feature) { 
     DefectStatus status = null 
     try{ 
      status = getDefectStatus(knownIssue.value()) 
     } catch(Exception ex){ 
      LOGGER.warn("Unable to determine defect status for defect ID '{}', test case {}", knownIssue.value(), feature.getName()) 
      // If we can't get info from Defect repository, just skip it, it should not cause failures or cause us not to execute tests. 
     } 
     if (status != null){ 
      if(!status.open && !status.fixed){ 
       LOGGER.error("Defect with ID '{}' and title '{}' is no longer in an open status and is not fixed, for test case '{}'. Update or remove test case.", knownIssue.value(), status.defectTitle, feature.getName()) 
       feature.addInterceptor(new CauseFailureInterceptor("Defect with ID '" + knownIssue.value() + "' and title '" + status.defectTitle + "' is no longer in an open status and is not fixed, for test case '" + feature.getName() + "'. Update or remove test case.")) 
      }else if (status.open && !status.fixed){ 
       LOGGER.warn("Defect with ID '{}' and title '{}' is still open and has not been fixed. Not executing test '{}'", knownIssue.value(), status.defectTitle, feature.getName()) 
       feature.setSkipped(true) 
      }else if (!status.open && status.fixed){ 
       LOGGER.error("Defect with ID '{}' and title '{}' has been fixed and closed. Remove KnownIssue annotation from test '{}'.", knownIssue.value(), status.defectTitle, feature.getName()) 
       feature.addInterceptor(new CauseFailureInterceptor("Defect with ID '" + knownIssue.value() + "' and title '" + status.defectTitle + "' has been fixed and closed. Remove KnownIssue annotation from test '" + feature.getName() + "'.")) 
      }else { // status.open && status.fixed 
       LOGGER.warn("Defect with ID '{}' and title '{}' has recently been fixed. Remove KnownIssue annotation from test '{}'", knownIssue.value(), status.defectTitle, feature.getName()) 
      } 
     } 
    } 

    public abstract DefectStatus getDefectStatus(String defectId) 

} 

public class CauseFailureInterceptor extends AbstractMethodInterceptor{ 
    public String failureReason 
    public CauseFailureInterceptor(String failureReason = ""){ 
     this.failureReason = failureReason 
    } 

    @Override 
    public void interceptFeatureExecution(IMethodInvocation invocation) throws Throwable { 
     throw new Exception(failureReason) 
    } 
} 

class DefectStatus{ 
    boolean open 
    boolean fixed 
    String defectTitle 
} 
Problemi correlati