Как я могу издеваться над экземпляром с автосвязью в абстрактном тестовом классе? - PullRequest
0 голосов
/ 11 апреля 2020

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

abstract class SomeService<T extends SomeRepository<U>, U ...> {

    @Autowrired
    @Accessors(fluent = true)
    @Getter(PROTECTED)
    private U repositoryInstance;
}

Теперь я пытаюсь создать абстрактный тестовый класс для подклассов класса обслуживания.

@SpringBootTest
abstract class SomeServiceTest<T extends SomeService<U>, U extends SomeRepository<V>, V ...> {

    @Autowrired
    @Accessors(fluent = true)
    @Getter(PROTECTED)
    private T serviceInstance;

    // DOES NOT WORK!
    @MockBean
    @Accessors(fluent = true)
    @Getter(PROTECTED)
    private U repositoryInstance; // != serviceInstance.repositoryInstance();
}

Но насмешка над компонентом в тестовом классе действительного класса обслуживания работает.

class OtherServiceTest
        extends SomeServiceTest<OtherService, OtherRepository, ...> {

    @TestConfiguration
    OtherServiceTestConfiguration {

        // WORKS!!!
        // == serviceInstance().repositoryInstance();
        @MockBean private OtherRepository repositoryInstance;
    }
}

class AnotherServiceTest
        extends SomeServiceTest<AnotherService, AnotherRepository, ...> {

    // WORKS!!!
    // == serviceInstance().repositoryInstance();
    @MockBean private AnotherRepository repositoryInstance;
}

Как можно смоделировать SomeServiceTest#repositoryInstance, чтобы он ссылался на тот же объект, что и SomeServiceTest#serviceInstance.repositoryInstance()?

Ответы [ 2 ]

1 голос
/ 11 апреля 2020

Я не знаю, что такое @Autowire, потому что я использую @Autowired. Но, насколько я знаю, использование autowire в объявлении объекта - плохая практика.

Вместо:

@Autowired
MyObject myObject;

Используйте его в конструкторе:

Repository repository;    

@Autowired
public SomeService(Repository repository) {
    this.repository = repository;
}

А в вашем тесте:

class SomeServiceTest {

    @Mock
    private Repository repositoryMock;

    private Service serviceUnderTest;

    @Before
    public void init() {
         MockitoAnnotations.initMocks(this);
         serviceUnderTest = new Service(repositoryMock);
    }
0 голосов
/ 11 апреля 2020

Вы всегда можете объявить конструктор по умолчанию и все аргументы. Интегрированная среда DI будет создаваться через первый, внедряя поля с автопроводкой, тогда как вы можете создавать экземпляр с аргументом all-args из вашего тестового класса, передавая фиктивные объекты в качестве аргументов конструктора.

...