Внедрение зависимостей само по себе позволит вам внедрить реализацию IRepository, которая принимает любые вызовы, выполненные на нем, проверяет, удовлетворены ли инварианты и предварительные условия, и возвращает результаты, удовлетворяющие постусловиям. Когда вы решите внедрить фиктивный объект, который имеет очень конкретные ожидания относительно того, какие методы будут вызываться, тогда да, вы проводите тестирование с высокой степенью зависимости от реализации, но Dependency Injection совершенно невиновно в этом вопросе, так как оно никогда не диктует, ЧТО вам нужно. следует вводить; скорее, ваша говядина, по-видимому, связана с Mocking - на самом деле, в частности, с несколько автоматизированным подходом Mocking, который вы выбрали, который основан на очень специфических ожиданиях.
Насмешка с очень конкретными ожиданиями действительно полезна только для тестирования белого ящика. В зависимости от используемых инструментов / платформ / библиотек (и вы даже не указываете точный язык программирования в теге, поэтому я предполагаю, что ваш вопрос полностью открыт), вы можете указать разрешенные степени свободы ( эти вызовы могут поступать в любых порядках, эти аргументы должны удовлетворять только следующим предварительным условиям и т. д. и т. д.). Тем не менее, я не знаю автоматизированного инструмента, который бы выполнял именно то, что вам нужно для непрозрачного тестирования, которое представляет собой «универсальную, толерантную реализацию интерфейса yonder со всеми необходимыми проверками« программирования по контракту », и нет». другой».
То, что я склонен делать в течение жизни проекта, - это создать библиотеку «не совсем издевательств» для основных необходимых интерфейсов. В некоторых случаях это может быть несколько очевидно с самого начала, но в других случаях они появляются постепенно, так как я рассматриваю некоторые основные рефакторинг, как показано ниже (типичный сценарий) ...:
На ранних этапах рефакторинга нарушаются некоторые аспекты хрупкой насмешки над сильными ожиданиями, которую я изначально дешево применил, я размышляю, стоит ли просто подстроить ожидания или пойти на все, если я решу, что это не разовое (т. е. отдача от будущих рефакторингов и тестов оправдает инвестиции), тогда я вручную пишу хороший «не совсем издевательский» материал и прячу его в специальном пакете трюков проекта, который часто можно использовать в разных проектах; такие классы / пакеты, как MockFilesystem, MockBigtable, MockDom, MockHttpClient, MockHttpServer и т. д., и т. д., попадают в независимый от проекта репозиторий и повторно используются для тестирования всех видов будущих проектов (и фактически могут использоваться совместно с другими командами в компании, если несколько команд используют интерфейсы файловой системы, интерфейсы больших таблиц, DOM, http-клиент-серверные интерфейсы и т. д. и т. д., которые одинаковы для всех групп).
Я признаю, что использование слова «mock» может быть немного неуместным, если вы берете «mock», чтобы ссылаться конкретно на стиль точного ожидания «поддельной реализации для целей тестирования» интерфейсов. Может быть, Stub, Shim, Fake, Test или какой-то другой префикс все же может быть предпочтительным (я склонен использовать Mock по историческим причинам, за исключением случаев, когда я специально называю его Fake или подобным; -).
Если бы я использовал языки с ясным и точным способом выражения в самом языке различных спецификаций проектирования по контракту в интерфейсе, я думаю, что я бы получил автоматическую поддержку инструментов для большей части этого подделка / прокладки / и т.д.; однако я в основном пишу на других языках, поэтому здесь мне нужно немного больше ручного труда. Но я думаю, что это отдельная проблема.