Fix JUnit - Autowire Clock - PullRequest
       43

Fix JUnit - Autowire Clock

0 голосов
/ 14 октября 2018

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

enter image description here

Часы определены в файле конфигурации как

@Qualifier("helperClock")
@Bean
public Clock helperClock() {
    return Clock.systemDefaultZone();
}

Мне нужно написать JUnit для 2 классов:

1) Test HelperClass1 Мой код - не работает

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest
    public class HelperClass1Test {
        @MockBean
        private Clock helperClock;
        @Autowired
        private HelperClass1 helperClass1;

        @Before
        public void init() {
            helperClock=Clock.fixed(Instant.parse("2017-12-03T10:15:30.00Z"),ZoneId.systemDefault());
        }   

        @Test
        public void testSomeHelperMethod1() {
            helperClass1.someHelperMethod1(); // I WANT mocked helperClock to be injected into HelperClass1 and used.
        }
    }

2) Проверить ImplClass - не работает

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class HelperClass1Test {
    @MockBean
    private Clock helperClock;
    @Autowired
    private SomeServiceImpl someServiceImpl;

    @Before
    public void init() {
        helperClock=Clock.fixed(Instant.parse("2017-12-03T10:15:30.00Z"),ZoneId.systemDefault());
    }   

    @Test
    public void testSomeServiceMethod() {
        someServiceImpl.SomeServiceMethod(); // I WANT mocked helperClock to be injected into HelperClass1 and used.
    }
}

Как мне исправить этот код?

1 Ответ

0 голосов
/ 14 октября 2018

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

С учетом сказанного есть три вещи, которые я бы порекомендовал вам сделать.

  1. Укажитепрофиль для ваших тестов.Вы можете использовать «test», если хотите.
  2. Создайте bean-компоненты, которые находятся под вашим тестовым профилем, и используйте их для инъекций.
  3. Избегайте использования mocks. ОниЗаманчиво и может быть полезно, но если вы планируете использовать возможности Spring впрыскивания, лучше сразу от них отказаться.

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

  • Я заставляю bean-компонент Clock быть основным, так что это будет авторитетный Clock bean-компонент, используемый в этом тестовом контексте.
  • Я заставляю профиль «тестировать», чтобы можно было подключить bean-компоненты под этим профилем.
  • Я гарантирую, что добавлю этот bean-компонент в контекстное сканирование внутри теста, добавив запись классак аннотации SpringBootTest.
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {
        YourSpringBootContextClassIfApplicable.class,
        HelperClass1Test.HelperClass1TestConfiguration.class
})
@ActiveProfiles("test")
public class HelperClass1Test {

    @Autowired
    private HelperClass1 helperClass1;

    @Test
    public void testSomeHelperMethod1() {
        helperClass1.someHelperMethod1();
    }

    @Configuration
    @Profile("test")
    static class HelperClass1TestConfiguration {

        @Bean
        @Primary
        public Clock helperClock() {
            return Clock.fixed(Instant.parse("2017-12-03T10:15:30.00Z"), ZoneId.systemDefault());
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...