Сравнение свойств вложенных объектов с использованием SemanticComparison

StackOverflow https://stackoverflow.com//questions/21022685

Вопрос

Я создаю тест на единицу, которым нужно будет сравнивать два объекта одного и того же типа. Я решил использовать SEMANTICCOMPROSONOSONISON для обработки этой задачи без записи пользовательского кода сравнения. Он работает очень хорошо при сравнении плоских объектов, существуют проблемы, когда объект содержит вложенный объект, который также необходимо сравнить элемент пользователя.

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"
            }
        };
    }
}
.

Это не будет работать, потому что внутренний объект сравнивается со ссылкой, а не элемент-раз:

    [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);
    }
.

Чтобы сделать это работать, мне пришлось создать прокси вложенный объект, чтобы он переопределил по умолчанию, равно реализацию.

    [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);
    }
.

Ну, работает правильно, но представьте, что после некоторого рефакторинга кода обслуживания мы представляем ошибку, вызывающую свойство значения внутреннего класса отличаться от ожидаемого значения. Классная особенность семантикМарисона состоит в том, что она может регистрировать имя участника, который вызывает неравенство. Но в этом случае он только вернет «внутреннее» как несоответствие, а не имя конкретного свойства во внутреннем классе.

Я что-то упускаю? Можно ли настроить его, чтобы иметь возможность вернуть фактический элемент несоответствия.

Это, очевидно, не проблема для простых структур данных, как в этом примере, но это может быть неудобство для тестирования реального режима жизни.

Это было полезно?

Решение

Поскольку никто не ответил, я предоставлю свой собственный ответ.

Так, кажется, вы не можете сделать это OOTB, если вы не пишете дополнительный код. Я завернул код в наборе методов расширения. Эти методы позволяют указать, какие свойства внутреннего свойства / сбора следует сравнивать с использованием внутренней сходства, а не посредством ссылки. Вам не нужно создавать какие-либо прокси вручную, все обрабатывается внутри этих расширений. И результаты всех внутренних сравнений регистрируются, так что вы можете точно видеть, какой элемент имеет неверное значение.

Вот тест от вопроса с использованием метода расширения «внутренней льдины».

    [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);
    }
.

Вы можете видеть свойства значения внутренних объектов не совпадают, поэтому тест должен потерпеть неудачу. И это не удается со следующими сообщениями на выходе:

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.
.

Вы можете найти исходный код и больше примеров на GitHub.

https://github.com/jmansar/semanticComparisonextionsions

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top