Spring Data JPA -为什么我在测试中得到空bean异常



我想使用Spring Data JPA来做ORM。我有以下声明的存储库接口:

public interface SegmentRepository extends JpaRepository<Segment, Integer> {
    // query methods ...
}

下面是Java的Config类:

@Configuration
@EnableJpaRepositories("com.example.cap.repositories")
@EnableTransactionManagement
public class CAPRepositoryConfig {
    @Bean
    public DataSource dataSource() {
        BasicDataSource ds = new BasicDataSource();
        ds.setDriverClassName(org.postgresql.Driver.class.getName());
        ds.setUsername("postgres");
        ds.setPassword("password");
        ds.setUrl("jdbc:postgresql://localhost:5432/postgres");
        ds.setInitialSize(10);
        return ds;
    }
    @Bean
    public EntityManagerFactory entityManagerFactory() {
        EclipseLinkJpaVendorAdapter vendorAdapter = new EclipseLinkJpaVendorAdapter();
        vendorAdapter.setGenerateDdl(true);
        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        Map<String, Object> jpaProperties = new HashMap<String, Object>();
        jpaProperties.put("eclipselink.weaving", "false");
        factory.setJpaVendorAdapter(vendorAdapter);
        factory.setPackagesToScan("com.example.cap.repositories");
        factory.setDataSource(dataSource());
        factory.setJpaPropertyMap(jpaProperties);
        factory.afterPropertiesSet();
        return factory.getObject();
    }
    @Bean
    public PlatformTransactionManager transactionManager() {
        JpaTransactionManager txManager = new JpaTransactionManager();
        txManager.setEntityManagerFactory(entityManagerFactory());
        return txManager;
    }
}

Segment类在com.example.cap.repositories中定义为:

@Entity
public class Segment {
    @Id
    private int segmentID;
    private int caseID;
    private Timestamp segStartTime;
    private Timestamp segEndTime;
    //setter and getters
}

但是,当我使用自动注入bean SegmentRepository运行JUnit测试时,我得到了bean repository的零点异常:

@ContextConfiguration(classes=CAPRepositoryConfig.class)
public class CAPRepositoryTest {
    @Autowired
    private SegmentRepository repository;
    @Test
    public void testRepository() {
        Segment seg = repository.findOne(123);    //null pointer exception for repository
    }
}

根据Spring Data JPA文档,只要我在Java配置类中指定@EnableJpaRepositories, SegmentRepository bean repository应该被自动注入。但是为什么我在JUnit测试类中得到repository的空指针异常?因为SegmentRepository是一个接口而不是一个类,所以我不能通过Java Config类创建实例。

我想你忘记了SpringJUnit4ClassRunner,它使@Autowired在测试中工作:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=CAPRepositoryConfig.class)
public class CAPRepositoryTest { ... }

当我使用测试类并且我需要做单元测试时,我更喜欢实例化类,因为尽管您有接口,但您也需要有实现类。在我的例子中,我这样做:

 @ContextConfiguration(classes=CAPRepositoryConfig.class)
 public class CAPRepositoryTest {
     private SegmentRepository repository;
     @Before
     public void testRepository() {
         repository = new SegmentRepositoryImpl();
     }
     @Test
     public void testRepository() {
         Segment seg = repository.findOne(123);
     }
 }

最新更新