Почему @ComponentScan не работает DataMongoTest - PullRequest
1 голос
/ 02 июня 2019

Существует класс Монго Дао com.foo.bar.dao.CompanyRecommendationDao, и существует соответствующий класс тестирования: com.foo.bar.dao.CompanyRecommendationDaoTest.

@RunWith(SpringRunner.class)
@DataMongoTest(includeFilters = @ComponentScan.Filter(type= FilterType.ASSIGNABLE_TYPE,value={CompanyRecommendationDao.class}))
@Import(SpringMongoConfig.class)
public class CompanyRecommendationDaoTest

При первом запуске тестовый класс в порядке, но если добавить аннотацию ComponentScan над классом приложения

@SpringBootApplication
@ComponentScan("com.foo")
public class BarApplication 

, в этом случае при запуске CompanyRecommendationDaoTest может получиться ошибка ниже

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'companyManagementService': Unsatisfied dependency expressed through field 'companyMapper'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'companyMapper' defined in file [/Users/zhugw/develop/workspace/bar/target/classes/com/foo/bar/mapper/CompanyMapper.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required

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

From DataMongoTest javadoc

Может использоваться, когда тест фокусируется только на компонентах MongoDB.Использование этой аннотации отключит полную автоконфигурацию и вместо этого будет применять только конфигурацию, относящуюся к тестам MongoDB.

Какая разница, если явно добавить @ComponentScan ("com.foo") (по умолчанию используется пакет com.foo.bar)?

PS.При включении журнала трассировки

Ситуация 1 (без @ComponnetScan)

2019-06-02 22:28:08.876 TRACE 13875 --- [           main] o.s.c.a.ClassPathBeanDefinitionScanner   : Scanning file [/Users/zhugw/develop/workspace/foo/bar/target/classes/com/foo/bar/dao/CompanyRecommendationDao.class]
2019-06-02 22:28:08.877 TRACE 13875 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'org.springframework.boot.test.context.filter.TestTypeExcludeFilter'
2019-06-02 22:28:08.877 TRACE 13875 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'org.springframework.boot.test.autoconfigure.filter.TypeExcludeFilters'
2019-06-02 22:28:08.877 DEBUG 13875 --- [           main] o.s.c.a.ClassPathBeanDefinitionScanner   : Identified candidate component class: file [/Users/zhugw/develop/workspace/foo/bar/target/classes/com/foo/bar/dao/CompanyRecommendationDao.class]

Ситуация 2 (с @ComponnetScan)

2019-06-02 22:40:23.989 TRACE 14573 --- [           main] o.s.c.a.ClassPathBeanDefinitionScanner   : Scanning file [/Users/zhugw/develop/workspace/foo/bar/target/classes/com/foo/bar/dao/CompanyRecommendationDao.class]
2019-06-02 22:40:23.989 DEBUG 14573 --- [           main] o.s.c.a.ClassPathBeanDefinitionScanner   : Identified candidate component class: file [/Users/zhugw/develop/workspace/foo/bar/target/classes/com/foo/bar/dao/CompanyRecommendationDao.class]

Ответы [ 2 ]

1 голос
/ 03 июня 2019

Проблема, с которой вы столкнулись, может быть связана с @ComponentScan.Изначально, когда вы используете аннотацию @DataMongotTest only, пружина настраивает компоненты, необходимые для запуска только монго. Но когда вы добавляете аннотацию сканирования компонентов в основной класс и устанавливаете уровень сканирования пакета, как "com.foo", пружина будет автоматически искать инайдите bean-компоненты для регистрации во всех пакетах по этому пути.

Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required

Так как вы не предоставляете данные приложения в целом, включая значения свойств и т. д., когда запускаете test, Spring не может создать bean-компонент для sqlSessionTemplate.java, которым могут понадобиться некоторые значения свойств, которые не загружаются в тесте.

Аннотация, которую можно использовать в сочетании с @RunWith (SpringRunner.class) для типичного теста MongoDB.Может использоваться, когда тест фокусируется только на компонентах MongoDB.Использование этой аннотации отключит полную автоконфигурацию и вместо этого будет применять только конфигурацию, относящуюся к тестам MongoDB.По умолчанию тесты, аннотированные @DataMongoTest, будут использовать встроенный процесс MongoDB в памяти (если доступен).

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

См. здесь

0 голосов
/ 09 июня 2019

Причина:

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

https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html

Resolve:

  1. Определяет фильтры исключенияявно
    @ComponentScan(value="com.foo",excludeFilters = { @ComponentScan.Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class) })

Если вы напрямую используете @ComponentScan (то есть не через @SpringBootApplication), вам необходимо зарегистрировать TypeExcludeFilter в нем.См. Javadoc для деталей.

Имейте отдельный основной класс, определенный в том же пакете, что и класс теста (например, CompanyRecommendationDaoTest)
    @SpringBootApplication
    public class DaoTestApplication {

        public static void main(String[] args) {
            SpringApplication.run(DaoTestApplication.class, args);
        }

    }

...