Подпуть контекста FluentAssertions AssertionScope

Есть ли способ указать, что приводит к добавлен ключу {context} встроенных утверждений или потенциально получить значение этого контекста?

Образец

Например. Мне удалось добавить пользовательские утверждения с помощью ключей AssertionSope к пользовательскому Execution.Assertions следующим образом:

Примеры классов

public class Foo
{
    public Bar Bar { get; } = new Bar();
}

public class Bar
{
    public bool IsFull {get; set; }
}

Классы расширения

public static class Extensions
{
    public static FooAssertions Should(this Foo foo) => new FooAssertions(foo);
    public static BarAssertions Should(this Bar bar) => new BarAssertions(bar);

    public class FooAssertions
    {
        public Foo Subject { get; }

        public FooAssertions(Foo subject)
        {
            Subject = subject;
        }

        [CustomAssertion]
        public void HaveFullBar(string because = null, params object[] becauseArgs)
        {
            using (var scope = new AssertionScope())
            {
                scope.AddReportable("SubPath", "." + nameof(Foo.Bar));

                Subject.Bar.Should().BeFull(because, becauseArgs);
            }
        }
    }

    public class BarAssertions
    {
        public Bar Subject { get; }

        public BarAssertions(Bar subject)
        {
            Subject = subject;
        }

        [CustomAssertion]
        public void BeFull(string because = null, params object[] becauseArgs)
        {
            Execute.Assertion
                .ForCondition(Subject.IsFull)
                .BecauseOf(because, becauseArgs)
                .FailWith("Expected {context}{SubPath}.IsFull to be {0}{reason} but found {1}", true, Subject.IsFull);
        }
    }
}

Метод испытания

    [TestMethod]
    public void CustomTest()
    {
        var foo = new Foo();

        foo.Should().HaveFullBar();
    }

Выход

Output: Expected foo.Bar.IsFull to be True but found False

Вопрос

Как я могу добавить в сборку {context}, чтобы мне не пришлось заново изобретать колесо для каждого утверждения, которое уже предоставляет FluentAssertion?

Например. вызов стандартного BooleanAssertions.Should().BeTrue():

        [CustomAssertion]
        public void BeFull(string because = null, params object[] becauseArgs)
        {
            Subject.IsFull.Should().BeTrue();
        }

но это теряет SubPath.Bar.IsFull и выводит:

 Output: Expected foo to be true, but found False.

Попытки

Попытка первая

Пытался установить "контекст" внутренних областей утверждения на какое-то значение, но он теряет предыдущие значения!

        [CustomAssertion]
        public void HaveFullBar(string because = null, params object[] becauseArgs)
        {
            using (new AssertionScope(".Bar"))
            {
                Subject.Bar.Should().BeFull(because, becauseArgs);
            }
        }

        [CustomAssertion]
        public void BeFull(string because = null, params object[] becauseArgs)
        {
            using (new AssertionScope(".IsFull"))
            {
                Subject.IsFull.Should().BeTrue();
            }
        }

Это просто возвращает .IsFull, который является самым внутренним AssertionScope:

Expected .IsFull to be true, but found False.

Попытка вторая

Пытался добавить "{context}" в конструктор AssertionScope

        [CustomAssertion]
        public void HaveFullBar(string because = null, params object[] becauseArgs)
        {
            using (new AssertionScope("{context}.Bar"))
            {
                Subject.Bar.Should().BeFull(because, becauseArgs);
            }
        }
        [CustomAssertion]
        public void BeFull(string because = null, params object[] becauseArgs)
        {
            using (new AssertionScope("{context}.IsFull"))
            {
                Subject.IsFull.Should().BeTrue();
            }
        }

Это просто выводит самый внутренний {context}.IsFull

 Expected {context}.IsFull to be true, but found False.

Попытка третья

        [CustomAssertion]
        public void HaveFullBar(string because = null, params object[] becauseArgs)
        {
            using (new AssertionScope(AssertionScope.Current.Context + ".Bar"))
            {
                Subject.Bar.Should().BeFull(because, becauseArgs);
            }
        }

        [CustomAssertion]
        public void BeFull(string because = null, params object[] becauseArgs)
        {
            using (var scope = new AssertionScope(AssertionScope.Current.Context + ".IsFull"))
            {
                Subject.IsFull.Should().BeTrue();
            }
        }

По-прежнему теряет исходный контекст, так как первый AssertionScope.Current.Contextnull;

Выход:

Expected .Bar.IsFull to be true, but found False.

Есть ли у вас эти попытки где-нибудь в репозитории Git, которые я могу проверить?

Dennis Doomen 23.05.2018 08:49

@DennisDoomen Не сейчас, я, вероятно, подниму вопрос в репозитории FA, с этими тестами в репозитории форков, если это нормально?

Michal Ciechan 23.05.2018 11:51
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
511
0

Другие вопросы по теме