Pregunta

Estoy creando la prueba de la unidad que deberá comparar dos objetos del mismo tipo MI / AWIE. He decidido usar la biblioteca SemanticComparison para manejar esta tarea sin escribir un código comparativo personalizado. Funciona muy bien cuando se comparan objetos planos, hay problemas cuando el objeto contiene un objeto anidado que también necesita ser comparado a Miembros.

public class Outer
{
    public string Name { get; set; }
    public Inner Inner { get; set; }
}

public class Inner
{
    public string Name { get; set; }
    public string Value { get; set; }
}

public class Service
{
    public Outer Method()
    {
        return new Outer()
        {
            Name = "outerName",
            Inner = new Inner()
            {
                Name = "innerName",
                Value = "value1"
            }
        };
    }
}

Esto no funcionará porque el objeto interno se compara con referencia, no a la persona:

    [Test]
    public void SimpleTest1()
    {

        // setup
        var expectedLikeness = new Outer()
        {
            Name = "outerName",
            Inner = new Inner()
            {
                Name = "innerName",
                Value = "value1"
            }
        }.AsSource().OfLikeness<Outer>();

        var sut = new Service();
        // exercise sut
        var actual = sut.Method();
        // verify
        expectedLikeness.ShouldEqual(actual);
    }

Para que funcione. Tuve que crear un proxy del objeto anidado para que anule la implementación de iguales predeterminada.

    [Test]
    public void SimpleTest2()
    {

        // setup
        var expectedLikeness = new Outer()
        {
            Name = "outerName",
            Inner = new Inner()
            {
                Name = "innerName",
                Value = "value1"
            }.AsSource().OfLikeness<Inner>().CreateProxy()
        }.AsSource().OfLikeness<Outer>();

        var sut = new Service();
        // exercise sut
        var actual = sut.Method();
        // verify
        expectedLikeness.ShouldEqual(actual);
    }

Bueno, funciona correctamente, pero imagina que después de un poco de refactorización del código de servicio, presentamos el error que causa que la propiedad de valor de la clase interna sea diferente del valor esperado. La característica fresca de la Comparación SemanaticParison es que puede registrar el nombre del miembro que causa la desigualdad. Pero, en este caso, solo volverá "interno" como desajuste, no el nombre de la propiedad específica en la clase interna.

¿Estoy perdiendo algo? Es posible configurarlo para poder devolver el miembro de desajuste real.

Obviamente, esto no es un problema para las estructuras de datos simples que en este ejemplo, pero podría ser un inconveniente para probar un código de vida real.

¿Fue útil?

Solución

Dado que nadie respondió, proporcionaré mi propia respuesta.

Entonces, parece que no puede hacerlo ootb, a menos que escriba un código extra. He envuelto el código en conjunto de métodos de extensión. Estos métodos le permiten especificar qué propiedades / propiedades de recolección interiores deben compararse con la semejanza interna, no como referencia. No necesita crear ningún proxies manualmente, todo se maneja internamente por estas extensiones. Y los resultados de todas las comparaciones internas se registran, por lo que puede ver exactamente qué miembro tiene valor no válido.

Aquí está la prueba de la pregunta con el uso del método de extensión "DIERNNERLIZIDA".

    [Test]
    public void ServiceTest3()
    {
        // setup
        var expected = new Outer()
        {
            Name = "outerName",
            Inner = new Inner()
            {
                Name = "innerName",
                Value = "value2"
            }
        };

        var expectedLikeness = expected.AsSource().OfLikeness<Outer>()
            .WithInnerLikeness(d => d.Inner, s => s.Inner)
            ;

        var sut = new Service();
        // exercise sut
        var actual = sut.Method();
        // verify
        expectedLikeness.ShouldEqual(actual);
    }

Puede ver que las propiedades de valor de los objetos interiores no coinciden, por lo que la prueba debe fallar. Y falla con los siguientes mensajes en la salida:

Comparing inner properties using likeness. Source: s => s.Inner Destination: d => d.Inner.
The source and destination values are not equal. Details: The provided value ClassLibrary1.Inner did not match the expected value ClassLibrary1.Inner. The following members did not match:
- Value.

Ploeh.SemanticComparison.LikenessException : The provided value ClassLibrary1.Outer did not match the expected value ClassLibrary1.Outer. The following members did not match:
- Inner.

Puede encontrar el código fuente y más ejemplos en GitHub.

https://github.com/jmansar/semanticomparisonextensions

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