当前位置: 首页 > 知识库问答 >
问题:

Spring Boot DataJpaTest fail with java.lang.IllegalStateException:原因:给定类型必须是接口

施翰学
2023-03-14

确切的说要看我有什么错误。

如果我使用Intellij Maven Install,我会得到这个异常(这很奇怪,因为我有这种依赖关系,如果我没有错,它应该默认在spring-starter-test中):

Caused by: java.lang.ClassNotFoundException: ch.qos.logback.classic.turbo.TurboFilter

但是如果我直接在problematic test class中开始测试,我会得到以下异常:

o.s.test.context.TestContextManager      : Caught exception while allowing TestExecutionListener [org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener@217ed35e] to prepare test instance [mypackage.DataBaseTest@279fedbd]
java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125) ~[spring-test-5.1.4.RELEASE.jar:5.1.4.RELEASE]
...
Caused by: java.lang.IllegalArgumentException: Given type must be an interface!
    at org.springframework.util.Assert.isTrue(Assert.java:118) ~[spring-core-5.1.4.RELEASE.jar:5.1.4.RELEASE]

对于第一个异常(maven->install),我不理解,我有那个类的jar。

-External Libraries
    |
    |
    |--- Maven: ch.qos.logback:logback-classic:1.2.3
         |---logback-classic-1.2.3.jar
             |
             |---turbo
                 |
                 |---TurboFilter

对于第二个异常,我无法理解@datajpatest是否创建了所有内容。我尝试了@springboottest(以为它可以是我在autowired存储库中使用的@service)。

我的pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.8.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
...
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jms</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
         </dependency>
    <dependency>
        <groupId>weblogic</groupId>
        <artifactId>wljmsclient</artifactId>
        <version>12.1.1</version>
        <scope>provided</scope>
    </dependency>
    <!-- Tomcat embedded container-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.12</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>com.oracle.jdbc</groupId>
        <artifactId>ojdbc8</artifactId>
        <version>12.2.0.1</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
        <version>5.6.2</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <version>1.4.200</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.3</version>
        <scope>test</scope>
    </dependency>

应用程序配置:

@Configuration
@EnableJms
@EnableJpaRepositories
@PropertySource({"classpath:some.properties"})
public class ApplicationConfig {
...

private Properties getJNDiProperties() {
    final Properties jndiProps = new Properties();
    jndiProps.setProperty(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
    return jndiProps;
}
@Bean
public JndiTemplate jndiTemplate() {
    final JndiTemplate jndiTemplate = new JndiTemplate();
    jndiTemplate.setEnvironment(getJNDiProperties());
    return jndiTemplate;
}

application.properties文件:

spring.datasource.jndi-name=jdbc/myDataSource
spring.jpa.database-platform=org.hibernate.dialect.Oracle10gDialect
spring.jpa.show-sql=false
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.generate-ddl=false
package myPackage;

import myPackage.repository.MyRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import static org.assertj.core.api.Assertions.assertThat;

@DataJpaTest
public class DataBaseTest {


    @Autowired
    private DataSource dataSource;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private EntityManager entityManager;
    @Autowired
    private MyRepository myRepository;

    @Test
    public void injectedComponentsAreNotNull(){
        assertThat(dataSource).isNotNull();
        assertThat(jdbcTemplate).isNotNull();
        assertThat(entityManager).isNotNull();
        assertThat(myRepository).isNotNull();
    }
}

已更新

因此,对于@datajpatest,我添加了@import(MyRepository.class),但也有相同的例外。

Maven->安装

Caused by: java.lang.ClassNotFoundException: ch.qos.logback.classic.turbo.TurboFilter
o.s.test.context.TestContextManager      : Caught exception while allowing TestExecutionListener [org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener@217ed35e] to prepare test instance [mypackage.DataBaseTest@279fedbd]
java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125) ~[spring-test-5.1.4.RELEASE.jar:5.1.4.RELEASE]
...
Caused by: java.lang.IllegalArgumentException: Given type must be an interface!
    at org.springframework.util.Assert.isTrue(Assert.java:118) ~[spring-core-5.1.4.RELEASE.jar:5.1.4.RELEASE]
            <plugin>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>${maven-surefire-plugin.version}</version>
            <configuration>
                <classpathDependencyExcludes>
                    <classpathDependencyExcludes>ch.qos.logback:logback-classic</classpathDependencyExcludes>
                </classpathDependencyExcludes>
            </configuration>
        </plugin>
Caused by: java.lang.IllegalArgumentException: Given type must be an interface!

更新3

最后,我取得了进步。我需要的是@EnableAutoConfiguration。我以为@datajpatest会为我做一些事情,但很明显,它有一个问题。

Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Schema "MYSCHEMA" not found; SQL statement:

我有实体像:

@Getter
@Setter
@ToString
@Builder(toBuilder=true)
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(of = "logId")
@Entity
@Table(name = "MY_TABLE", schema = "MYSCHEMA", catalog = "")
public class MyEntity {
@TestPropertySource(properties = "spring.jpa.properties.hibernate.default_schema=PETRA")

共有1个答案

史默
2023-03-14

您的@datajpatest不需要@enableAutoConfiguration,因为注释启用了测试应用程序的这一部分所需的每个部分:

// ... and some more
@BootstrapWith(DataJpaTestContextBootstrapper.class)
@ExtendWith(SpringExtension.class)
@OverrideAutoConfiguration(enabled = false)
@TypeExcludeFilters(DataJpaTypeExcludeFilter.class)
@Transactional
@AutoConfigureCache
@AutoConfigureDataJpa
@AutoConfigureTestDatabase
@AutoConfigureTestEntityManager
@ImportAutoConfiguration
public @interface DataJpaTest {

}

需要指出的是,对于@datajpatestSpring默认情况下将使用嵌入式内存数据库:

 * By default, tests annotated with {@code @DataJpaTest} are transactional and roll back
 * at the end of each test. They also use an embedded in-memory database (replacing any
 * explicit or usually auto-configured DataSource). The
 * {@link AutoConfigureTestDatabase @AutoConfigureTestDatabase} annotation can be used to
 * override these settings.

这就是为什么您看到的是H2数据库输出,而不是Oracle。默认情况下,Spring应该使用Spring.jpa.hibernate.ddl-auto=create-drop来确保表是否存在。

在使用@table(name=“my_table”,schema=“myschema”,catalog=“”)硬编码JPA实体中的模式时,必须确保嵌入的H2也使用此模式。

首先尝试从@table注释中删除schema并看看它是否起作用。然后可以在application.properties中全局配置架构,并使用@TestPropertySource(properties=“spring.jpa.properties.hibernate.default_schema=petra”)进行测试。

下面的StackOverflow问题可能也有帮助。

 类似资料:
  • 在以下代码中,我得到了此错误: TypeError[ERR_INVALID_ARG_TYPE]:原始参数的类型必须是Function。接收类型未定义 它说问题在第31行: 我在使用promisify图书馆时遇到问题。

  • 问题内容: 在Objective-C中,您可以将类型定义为给定类并实现协议: 这将表明返回的值是实现给定协议的值。有没有办法在Swift中执行类似的操作? 问题答案: 您可以这样做: 这定义了一个函数,该函数返回类型为“SomeType”和协议“SomeProtocol”的对象,并返回符合这些条件的对象。

  • 问题内容: 我正在尝试在Java中使用lambda和流,但我对此很陌生。当我尝试创建lambda表达式时,我在IntelliJ中收到了此错误“ lambda转换的目标类型必须是接口” 难道我做错了什么? 问题答案: 我怀疑这只是Java的类型推断不够聪明。尝试

  • 问题内容: 假设我有此接口A: 因此,我希望某些抽象类实现doThis()方法,而不是doThat()一个方法: 当您最终决定在常规类中实现de doThat方法时,就会出现错误: 此类导致我前面提到的错误: “类型B不能是C的超级接口;超级接口必须是接口” 现在任何人都可以,如果这种类层次结构有效,还是应该以其他方式进行处理? 问题答案: 您必须使用 了解和关键字之间的区别很重要。因此,我建议您

  • 问题内容: 我有以下代码: 注释行无法编译。 为什么即使协议要求,我也必须强制将协议类型对象强制转换为符合该对象类型的对象? 问题答案: 采用该协议告诉编译器此特定响应,至少不会更多。 在相反的结论,并 没有 成为必然。 如果受影响的类不是,约束只是编译器 在编译时 抱怨的另一信息。 在您的情况下,对编译器进行批注仅知道对作出响应。它不知道类型实际上是的子类。 因此,如果要访问具体类的属性,请不要

  • 我正在用python制作一个潜艇游戏,但当我试图运行它时,解释器给了我一个非常奇怪的错误:“TypeError:参数1必须是pygame.Surface,而不是type。”我试图在网上搜索我的答案,但这似乎不是很常见的错误。我也试着自己去发现错误,但我觉得一切都很好。下面是我认为错误所在的部分代码: