Autofixture: При желании отключить кеширование для AutoMoq?

Созданный на 20 мая 2016  ·  14Комментарии  ·  Источник: AutoFixture/AutoFixture

При использовании AutoConfiguredMoqCustomization значение, возвращаемое используемым прибором, кэшируется, и одно и то же значение будет возвращаться при каждом вызове (я не уверен, сделано ли это в MockType.ReturnsUsingContext или где-то еще, но я вижу комментарий об этом там строка 104).

Единственный способ, который я нашел, чтобы переопределить это, - передать замороженный экземпляр рассматриваемого макета в метод тестирования и переопределить настройку с помощью функции, вызывающей фикстуру:

someMock.Setup(it => it.SomeMethodReturningAString()).Returns(() => fixture.Create<string>())

Есть ли более универсальный / более умный способ настроить автоматически сгенерированные макеты для вызова прибора каждый раз, когда требуется значение из AutoFixture, кроме ручной настройки каждого вызова?

enhancement good first issue

Самый полезный комментарий

Признаюсь, я думал, что тестовые двойники были настроены на обратный вызов AutoFixture для получения возвращаемого значения. AutoFixture уже имеет механизм управления сроком службы (с помощью функций Freeze), поэтому я нахожу немного удивительным, что AutoConfiguredMoqCustomization реализует свой собственный диспетчер времени жизни и тем самым отменяет поверхность управления, которую предоставляет сама AutoFixture.

Все 14 Комментарий

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

Если тестируемая система ожидает чистой функции, но ей дана нечистая функция, тест, скорее всего, приведет к ложноположительному результату. Например

// This method will return the expected result *if* `GetInt` is pure.
int Double(IDependency dep) {
    return dep.GetInt() + dep.GetInt();
}

Assert.Equal(dep.GetInt * 2, Double(dep));

С другой стороны, если тестируемая система не предполагает чистоты, придание ей чистой или нечистой функции не должно иметь никакого значения.

Следовательно, когда я реализовал эту функцию, использование чистых функций по умолчанию имело для меня смысл.

Есть ли более универсальный / более умный способ настроить автоматически сгенерированные макеты для вызова прибора каждый раз, когда требуется значение из AutoFixture, кроме ручной настройки каждого вызова?

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

Если вы хотите сделать это для всех методов в нескольких тестах, вам потребуется немного больше работы:

  • Определите новую реализацию ReturnsUsingContext (IIRC, вы можете просто скопировать текущую реализацию и удалить строку 104)
  • Переопределите MockVirtualMethodsCommand и замените вызов ReturnsUsingContext вызовом вашего нового метода.
  • Переопределите AutoConfiguredMoqCustomization и замените создание экземпляра MockVirtualMethodsCommand экземпляром вашего нового класса.

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

Признаюсь, я думал, что тестовые двойники были настроены на обратный вызов AutoFixture для получения возвращаемого значения. AutoFixture уже имеет механизм управления сроком службы (с помощью функций Freeze), поэтому я нахожу немного удивительным, что AutoConfiguredMoqCustomization реализует свой собственный диспетчер времени жизни и тем самым отменяет поверхность управления, которую предоставляет сама AutoFixture.

Это очень хороший момент, я никогда не думал о Freeze таким образом. Я считаю, что изменение поведения настройки сейчас будет серьезным изменением ... как вы думаете, следует ли это изменить в AutoFixture v4?

Это поведение мы задокументировали или как-то «обещали» в тестах?

Удивительно, но нет. Я был почти уверен, что рассказал об этом, но, похоже, не стал. По крайней мере, я не смог найти ни одного теста, охватывающего это, и удаление этой строки не привело к сбою ни одного теста. Тем не менее, ИМО, это все еще наблюдаемое поведение, и, вероятно, будет код, который полагается на это ...

Честная оценка. Может быть, это значение конфигурации, которое мы установили на одно значение сейчас, а затем переключаем его при переходе на AutoFixture 4?

Согласовано. В этом контексте, что именно вы подразумеваете под «значением конфигурации»? Достаточно ли поднять его до константы внутри класса MockType ? Например, private const bool cacheReturnValues = true а затем if(cacheReturnValues) /**/

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

@andreasnilsen хотел бы изменить поведение сейчас, но мы это будет @andreasnilsen возможность изменить поведение сейчас, пока мы не

Когда мы представляем AutoFixture 4, мы меняем конфигурацию по умолчанию, так что поведение по умолчанию заключается в том, что возвращаемые значения не кэшируются. Или, возможно, мы просто удалим эту опцию ...

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

(Кроме того, если мы не абсолютно уверены, что будет только два значения, мы должны рассмотреть enum вместо bool .)

Ах, сначала я подумал, что вы имели в виду какой-то внутренний флаг, который было легко обнаружить и изменить в v4.

На ум приходят первые два подхода:

  • Просто добавьте логический параметр (необязательный, для обратной совместимости) в конструктор AutoConfiguredMoqCustomization , который затем будет распространен на MockVirtualMethodsCommand и на внутренний MockType.ReturnsUsingContext . Это кажется:

    1. немного запутанный и

    2. тоже _ad hoc_. Если бы мы захотели добавить дополнительные параметры конфигурации в настройку, конструктор стал бы слишком сложным и трудным для использования / обслуживания.

  • Используйте шаблон объекта параметра для решения проблемы (ii) выше.

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

Я думал что-то вроде стратегии ...

Ах да, конечно! Думаю, я был зациклен на «значении конфигурации» и забыл сделать шаг назад.

Прошу прощения за поздний ответ, меня завалили - я скоро посмотрю на это и вернусь с предложением по дизайну.

Недавно мы выполнили рефакторинг настройки, чтобы использовать свойства для настройки настройки. Потенциально, этой функцией можно управлять следующим образом (найдите лучшее название настройки):
c# new AutoMoqCustomization { CacheCallResults = false }

Под капотом мы могли бы реализовать это с помощью другой стратегии, подобной той, что была рекомендована выше.

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

@zvirja, не могли бы вы мне немного помочь, и я могу поработать над этим. Просто не знаю с чего начать :)

@micheleissa Спасибо за AutoMoq и отладить его, чтобы понять внутреннюю механику. Он очень маленький, так что времени на это не потребуется ...

Если у вас есть более конкретный вопрос, задавайте 😉

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

Eldar1205 picture Eldar1205  ·  5Комментарии

joelleortiz picture joelleortiz  ·  4Комментарии

ecampidoglio picture ecampidoglio  ·  7Комментарии

mjfreelancing picture mjfreelancing  ·  4Комментарии

zvirja picture zvirja  ·  4Комментарии