Внедрение Mocks на большой граф объектов зависимостей - PullRequest
4 голосов
/ 02 ноября 2011

У меня есть довольно значительный граф зависимостей для объекта, который я хочу проверить.Какой самый простой способ разрешить мои зависимости без необходимости везде регистрировать макеты?

Например, у меня есть такой график зависимости:

  PublicApi
    ApiService
      AccountingFacade
         BillingService
           BillingValidation
           BillingRepository
         UserService
           UserRepository

Я хочу проверить PublicApi.CreateUser(),и я хочу, чтобы он прошел через весь код, но я хочу смоделировать репозитории, чтобы мне не нужно было ничего записывать в базу данных.Должен ли я просто использовать DI-контейнер и зарегистрировать все свои службы, заменив репозитории на mocks, затем разрешив PublicApi и запустив метод?

Я искал AutoFixture, и похоже, что он можетсправиться с чем-то вроде этого, но я не могу обернуть голову вокруг всего «Freeze» против «Register» и его интеграции с Moq.

Ответы [ 2 ]

7 голосов
/ 02 ноября 2011

Для юнит-тестов вы должны только издеваться над прямыми зависимостями.В вашем случае вы создаете PublicApi и вводите макет для ApiService и проверяете, вызывает ли PublicApi соответствующие методы с правильными значениями в ApiService Mock.

Так же, как вы тестируете вседругие компоненты изолированы от более глубоких зависимостей.

Если вы хотите проверить комбинацию нескольких компонентов, это не модульное тестирование, а интеграционное тестирование.Поэтому это зависит от того, как вы проводите свои занятия вместе.например, если вы используете контейнер IoC, он, вероятно, поддерживает замену конфигурации для репозиториев каким-либо образом.В этом случае вы можете использовать конфигурацию приложения и заменить репозитории и, возможно, также представления на макеты.

1 голос
/ 02 ноября 2011

Это может быть бесполезно, но я все равно скажу.

Кажется, вы пытаетесь проверить слишком много сразу, почему бы просто не проверить BillingService -> BillingValidation, затем BillingService -> BillingRepositoryи т. д. Таким образом, у вас будет набор тестов, доказывающих, что каждый из них работает, тогда, когда вы находитесь на уровне PublicApi, вам нужно только смоделировать ApiService, так как вы уже проверили все под ним, поэтому нет смысла тестировать егоснова.

Как правило, я буду тестировать только 1 слой за один раз, но я не знаю ваш полный сценарий, поэтому у вас может быть что-то, что я не учитываю, так что если это так, и вам действительно нужно протестироватьвсе это вместе, я бы просто ввел простую и легкую структуру DI, такую ​​как Ninject или что-то в этом роде.

Таким образом, вы можете просто привязать все ваши типы к макетам, а затем создать из них свой PublicApi.

С ninject это будет выглядеть примерно так:

Kernel.Bind<UserRepository>.ToConst(YourMockUserRepositoryInstance);
Kernel.Bind<UserService>.ToConst(YourMockUserServiceInstance);
Kernel.Bind<BillingRepository>.ToConst(YourMockBillingRepositoryInstance);
Kernel.Bind<BillingValidation>.ToConst(YourMockBillingValidationInstance);
Kernel.Bind<BillingService>.ToConst(YourMockBillingServiceInstance);
Kernel.Bind<AccountingFacade>.ToConst(YourMockAccountingFacadeInstance);
Kernel.Bind<ApiService>.ToConst(YourMockApiServiceInstance);
Kernel.Bind<PublicApi>.ToSelf();

var publicApi = Kernel.Get<PublicApi>();

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...