Проблемы с использованием CreateProxy Autofixture для использования функций сходства, семантического сравнения

В предыдущем вопросе, который я задавал о методе CreateProxy от Autofixture, была обнаружена потенциальная ошибка.

Я не думаю, что этот неудачный тест является результатом этого, а скорее мое постоянное замешательство о том, как работает синтаксис Likeness.Without(...).CreateProxy(). Рассмотрим следующий неудачный тест, в котором я делаю исходный тест немного более сложным, создавая новый экземпляр объекта, считая его создание SUT:

[Fact]
public void Equality_Behaves_As_Expected()
{
    // arrange: intent -> use the fixture-created Band as Object Mother
    var template = new Fixture().Create<Band>();

    // act: intent -> instantiated Band *is* the SUT
    var createdBand = new Band {Brass = template.Brass,
                                Strings = template.Brass};

    //   intent -> specify that .Brass should not be considered in comparison 
    var likeness = template.AsSource().OfLikeness<Band>().
        Without(x => x.Brass).CreateProxy(); // Ignore .Brass property

    // per [https://stackru.com/a/15476108/533958] explicity assign
    // properties to likeness
    likeness.Strings = template.Strings;
    likeness.Brass = "foo"; // should be ignored

    // assert: intent -> check equality between created Band & template Band
    //         to include all members not excluded in likeness definition
    likeness.Should().Be(createdBand);          // Fails
    likeness.ShouldBeEquivalentTo(createdBand); // Fails
    Assert.True(likeness.Equals(createdBand));  // Fails
}

Вот группа:

public class Band
{
    public string Strings { get; set; }
    public string Brass { get; set; }
}

Мой предыдущий вопрос не был достаточно сложным, чтобы помочь мне понять, что Source из Likeness должно быть в общем.

Должен ли источник быть выходом SUT, в этом случае он будет сравниваться с экземпляром шаблона, созданным AutoFixture?

Или источником должен быть экземпляр шаблона, созданный AutoFixture, и в этом случае он будет сравниваться с выводом SUT?

РЕДАКТИРОВАТЬ: исправлена ​​ошибка в тесте

Я понял, что неправильно назначил template.Brass свойство как Brass и Strings собственность нового Band пример. Обновленный тест отражает коррекцию с var createdBand = new Band {Brass = template.Brass, Strings = template.Strings} и все шесть утверждений проходят.

[Fact]
public void Equality_Behaves_As_Expected()
{
    // arrange: intent -> use the fixture-created Band as Object Mother
    var template = new Fixture().Create<Band>();

    // act: intent -> instantiated Band *is* the SUT
    var createdBand = new Band {Brass = template.Brass, Strings = template.Strings};

    // likeness of created
    var createdLikeness = createdBand.AsSource().OfLikeness<Band>().
        Without(x => x.Brass).CreateProxy(); // .Brass should not be considered in comparison 

    // https://stackru.com/a/15476108/533958 (explicity assign properties to likeness)
    createdLikeness.Strings = createdBand.Strings;
    createdLikeness.Brass = "foo"; // should be ignored

    // likeness of template
    var templateLikeness = template.AsSource().OfLikeness<Band>()
        .Without(x => x.Brass)
        .CreateProxy();
    templateLikeness.Strings = template.Strings;
    templateLikeness.Brass = "foo";

    // assert: intent -> compare created Band to template Band
    createdLikeness.Should().Be(template);
    createdLikeness.ShouldBeEquivalentTo(template);
    Assert.True(createdLikeness.Equals(template));

    templateLikeness.Should().Be(createdBand);
    templateLikeness.ShouldBeEquivalentTo(createdBand);
    Assert.True(templateLikeness.Equals(createdBand));
}

1 ответ

Решение

Что вы имеете в виду:

likeness.Should().BeAssignableTo<Band>(); // Returns true.

В приведенном примере прокси, сгенерированный из Likeness это тип, происходящий от Bandпереопределяя Equals используя алгоритм семантического сравнения.

Используя Reflection, то есть:

createdBand.GetType().IsAssignableFrom(likeness.GetType()) // Returns true.

Обновление:

Экземпляры createBand и шаблона не зависят от CreateProxy метод. Почему они должны?

С Сходством CreateProxy вы в основном создаете пользовательское утверждение равенства, которое позволяет вам:

Assert.True(likeness.Equals(createdBand)); // Passed. 

Без этого первоначальное утверждение равенства не получится:

Assert.True(template.Equals(createdBand)); // Failed.

Однако следующее также не удастся:

Assert.True(likeness.Equals(template));

Это не удается, потому что Strings значение - это значение из экземпляра созданного фрагмента.

Такое поведение ожидается, и вы можете проверить это с помощью Likeness непосредственно:

 createdBand.AsSource().OfLikeness<Band>()
     .Without(x => x.Brass).ShouldEqual(template);

Выход:

 The provided value `Band` did not match the expected value `Band`. The following members did not match:
      - Strings.
Другие вопросы по тегам