Domanda

Sono in esecuzione alcuni test di unità su un servizio WCF. Il servizio è configurato per includere i dettagli di eccezione nella reazione all'anomalia (con il seguente nel mio file di configurazione del servizio).

<serviceDebug includeExceptionDetailInFaults="true" />

Se un test causa un'eccezione non gestita sul server il guasto viene ricevuto dal client con una completamente popolato traccia dello stack del server. Posso vedere questo chiamando il metodo ToString() del eccezione. Il problema è che questo non sembra essere emesso da una delle guide di test che ho provato (xUnit, Gallio, MSTest). Essi sembrano appena uscita il Messaggio e le proprietà StackTrace dell'eccezione.

Per illustrare ciò che intendo, la seguente unità di prova stamperà tre sezioni:

  • Messaggio di errore
  • Errore dello stack
  • Output console standard (contiene le informazioni Vorrei, per esempio "Guasto Particolare è pari ad un ExceptionDetail, probabilmente creato da IncludeExceptionDetailInFaults = true, il cui valore è: ..."

public void Test()
{
    try
    {
        service.CallMethodWhichCausesException();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex); // this outputs the information I would like
       throw;
    }
}

Modifica Tuttavia, io preferirei che non ero costretto a intercettare l'eccezione in ciascuna prova e scrivere alla console al fine di accertare il contenuto all'interno della proprietà FaultException di un oggetto Detail .

Ad esempio,

public void Test()
{
    service.CallMethodWhichCausesException();
}

Avere queste informazioni renderà la fase iniziale di test e implementazione molto meno doloroso.

So che posso solo avvolgere ogni unit test in un gestore di eccezioni generico e scrivere l'eccezione alla console e rethrow (come sopra) all'interno di tutti i miei test di unità, ma che sembra un modo molto prolisso di raggiungere questo (e apparirebbe abbastanza terribile).

Qualcuno sa se c'è un modo per ottenere queste informazioni incluse ogni volta che un non gestita si verifica un'eccezione? C'è un'impostazione che mi manca? È la mia configurazione di servizio privo di una corretta manipolazione colpa? Forse potrei scrivere una sorta di plug-in / adattatore per qualche quadro unit testing? Forse theres un framework di unit testing diversa che dovrei usare, invece!

Il mio attuale set-up è unit test xUnit eseguiti tramite Gallio per l'ambiente di sviluppo, ma ho una suite separata di "test di fumo" scritto, che mi piacerebbe essere in grado di avere i nostri tecnici eseguono tramite il test xUnit GUI corridore (o Gallio o qualsiasi altra cosa) per semplificare la distribuzione finale.

Grazie.

Adam

È stato utile?

Soluzione

Credo di aver trovato una soluzione. Oleg Sych ha implementato un comportamento WCF che modo trasparente marescialli eccezioni dal server al client, li alzando sul client, come se si fossero verificati lì.

E 'semplice come l'aggiunta di un attributo di comportamento servizio al contratto di servizio (interfaccia).

Questo approccio è particolarmente utile se si decide che il codice esistente, scritto da eseguire all'interno di un unico processo, dovrebbe distribuiti tramite servizi WCF. Ciò significa che può essere raggiunto senza la necessità di alcuna modifica la gestione delle eccezioni del cliente (ad esempio si può ancora gestire un SecurityException sul client invece di dover gestire una FaultException<SecurityException> quando si sposta in un design più distribuito).

Il post può essere trovato qui: http: //www.olegsych.com/2008/07/simplifying-wcf-using-exceptions-as-faults/

Dato che i miei servizi WCF utilizzano una miscela di ws2007HttpBinding del basicHttpBinding (per l'interoperabilità), ho dovuto fare alcune modifiche al codice (come indicato nei commenti del post precedente). In particolare:

In ExceptionMarshallingMessageInspector.AfterReceiveReply:

Exception exception = faultDetail as Exception;
if (exception != null)
{
    // NB: Error checking etc. excluded
    // Get the _remoteStackTraceString of the Exception class

    FieldInfo remoteStackTraceString = typeof(Exception).GetField(
        "_remoteStackTraceString",
        BindingFlags.Instance | BindingFlags.NonPublic);

    // Set the InnerException._remoteStackTraceString to the current InnerException.StackTrace
    remoteStackTraceString.SetValue(
        exception,
        exception.StackTrace + Environment.NewLine);

    throw exception;
}

... e in ExceptionMarshallingMessageInspector.ReadFaultDetail ho fatto un cambiamento in modo che appaia per un nodo dettaglio con un nome locale pari a uno "Detail" (per ws2007HttpBinding" o "dettaglio"(per basicHttpBinding).

Spero che questo aiuta.

Adam

Altri suggerimenti

uscita della console è disponibile come una colonna nella finestra dei risultati del test.

Gallio reindirizza l'output della console al suo registro di diagnostica per impostazione predefinita. Così si dovrebbe vedere le informazioni necessarie direttamente nel verbale di prova.

Nella sezione Dettagli del report HTML, ad esempio, espandere la struttura di prova e individuare il metodo di prova.

uscita della console nel rapporto di prova Gallio

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top