Pregunta

Estoy corriendo algunas pruebas unitarias en un servicio WCF. El servicio está configurado para incluir detalles de la excepción en la respuesta al fallo (con lo siguiente en mi archivo de configuración del servicio).

<serviceDebug includeExceptionDetailInFaults="true" />

Si una prueba provoca una excepción no controlada en el servidor de la falla es recibida por el cliente con un servidor de seguimiento de la pila totalmente poblada. Puedo ver esto llamando método ToString() de la excepción. El problema es que esto no parece ser la salida por cualquiera de los corredores de la prueba que he probado (xUnit, Galio, MSTest). Parece que acaba de emitir el mensaje y las propiedades StackTrace de la excepción.

Para ilustrar lo que quiero decir, la siguiente unidad de prueba de salida voluntad tres secciones:

  • Mensaje de error
  • Error de Seguimiento de la pila
  • Salida de consola estándar (contiene la información que me gustaría, por ejemplo, "Detalle de fallos es igual a un ExceptionDetail, probablemente creado por IncludeExceptionDetailInFaults = true, cuyo valor es: ..."

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

Editar Sin embargo, preferiría que no estaba obligado a coger la excepción en cada prueba y escribirla en la consola con el fin de determinar el contenido dentro de la propiedad FaultException de un objeto Detail .

Por ejemplo,

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

Tener esta información hará que la fase inicial de la prueba y el despliegue mucho menos doloroso.

Yo sé que sólo puede envolver cada unidad de prueba en un gestor de excepciones genéricas y escribir la excepción a la consola y volver a lanzar (como arriba) dentro de todas mis pruebas de unidad pero que parece una forma muy largo aliento de lograr esto (y se vería bastante horrible).

¿Alguien sabe si hay alguna manera de obtener esta información se incluye cada vez que un no controlada se produce una excepción? ¿Hay un ajuste que me falta? Es la configuración de mi servicio deficiente en el manejo de errores adecuado? Tal vez podría escribir algún tipo de plug-in / adaptador para algunos marco de pruebas de unidad? Tal vez theres un marco de pruebas de unidad diferente, que debería estar utilizando en su lugar!

Mi configuración actual es en las pruebas unitarias xUnit ejecutados a través de Galio para el entorno de desarrollo, pero tengo una suite independiente de "pruebas de humo" por escrito lo que me gustaría ser capaz de tener nuestros ingenieros se ejecutan a través de la prueba xUnit GUI corredor (o Galio o lo que sea) para simplificar el despliegue final.

Gracias.

Adam

¿Fue útil?

Solución

creo que he encontrado una solución. Oleg Sych ha puesto en marcha un comportamiento WCF que forma transparente mariscales excepciones desde el servidor al cliente, criarlos en el cliente como si hubieran ocurrido allí.

Es tan simple como añadir un atributo de comportamiento en servicio al contrato de servicios (interfaz).

Este enfoque es especialmente beneficioso si se decide que el código existente, escrita para ejecutar en un único proceso, debe distribuidos a través de servicios de WCF. Esto significa que se puede lograr sin requerir ningún cambio en el manejo de excepciones del cliente (por ejemplo, todavía se puede manejar una SecurityException en el cliente en lugar de tener que manejar una FaultException<SecurityException> cuando se mueve a un diseño más distribuida).

El puesto se puede encontrar aquí: http: //www.olegsych.com/2008/07/simplifying-wcf-using-exceptions-as-faults/

Desde mis servicios WCF están utilizando una mezcla de ws2007HttpBinding la basicHttpBinding (interoperabilidad), tuve que hacer algunos cambios en el código (como se menciona en los comentarios del post anterior). Específicamente:

En 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;
}

... y en ExceptionMarshallingMessageInspector.ReadFaultDetail me hizo un cambio para que se parezca a un nodo de detalle con un nombre local sea igual a "Detalle" (por ws2007HttpBinding" o 'detalle' (por basicHttpBinding).

Espero que esto ayude.

Adam

Otros consejos

salida de la consola está disponible como una columna en la ventana de resultados de prueba.

Galio redirige la salida de la consola a su registro de diagnóstico por defecto. Por lo que debe ver la información que necesita directamente en el informe de la prueba.

En la sección Detalles del informe HTML, por ejemplo, expanda el árbol de prueba y localizar su método de prueba.

salida de la consola en el informe de prueba Gallio

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top