如何在测试类中模拟JNDI数据源

时间:2019-09-19 01:59:42

标签: java spring unit-testing mocking mockito

我正在尝试测试我的DAO类,该类具有2个相关性,分别为dataSourcestringCrypto 但是应用程序不断抛出

Failed to obtain JDBC Connection: DataSource returned null from getConnection(): dataSource

我要模拟的数据源依赖关系是使用JndiDataSourceLookUp的bean

@Bean
public DataSource dataSource() {
    JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();

    dataSourceLookup.setResourceRef(true);

    DataSource dataSource = dataSourceLookup.getDataSource("castle/db");

    return dataSource;
}

这是DAO类

public class PersonDAOImpl implements PersonDAO {

@Autowired
private DataSource dataSource;

@Autowired
private Cryptography stringCrypto;

private NamedParameterJdbcTemplate namedParameterJdbcTemplate;

@Override
public List<Member> getAllMembers() {

    this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);

    try {
        List<Member> members = namedParameterJdbcTemplate.query(SqlStatement.GET_ALL_MEMBERS,
                new MemberExtractor());

        return members;
    } catch (Exception e) {
        e.printStackTrace();
        return null;

    }

}

正如您在本课程中所看到的,它具有2个依存关系,我正在下面的测试课程中模拟该依存关系

@RunWith(SpringRunner.class)
public class MembersControllerTest {

@Mock
DataSource dataSource;

@Mock
Cryptography stringCrypto;

@InjectMocks
PersonDAOImpl personDAOImpl;

@BeforeEach
void setUp() {
    MockitoAnnotations.initMocks(this);
}

@Test
public void test() {

    assertTrue(personDAOImpl.getAllMembers().size() > 0);

}

}

我尝试添加

@PostConstruct
private void initialization() {
    this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
}

但是它没有用,并且每当我运行测试时,它都无法获得jdbc连接。 抛出的异常根本没有帮助,所有其他类似的问题都与使用xml配置有关,接受的答案表明我真的不了解并且我甚至不想在我的XML中使用某些xml配置。应用。 我确实搜索了几乎所有相关问题,但都没有发现任何帮助,所以我决定问这个问题。

预先感谢

1 个答案:

答案 0 :(得分:1)

您仅在嘲笑DataSource,因此NamedParameterJdbcTemplate仍将调用getConnection()以获得连接并执行查询。推荐的方法是将NamedParameterJdbcTemplate声明为spring bean,然后您需要对其进行模拟

配置类

@Bean
public DataSource dataSource() {
  JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();

  dataSourceLookup.setResourceRef(true);

  DataSource dataSource = dataSourceLookup.getDataSource("castle/db");

  return dataSource;
}

 @Bean
 public NamedParameterJdbcTemplate namedParameterJdbcTemplate(DataSource dataSource) {
   return new NamedParameterJdbcTemplate(dataSource);

}

测试课程

 @RunWith(SpringRunner.class)
 public class MembersControllerTest {

     @Mock
     DataSource dataSource;

     @Mock
     Cryptography stringCrypto;

     @Mock
     NamedParameterJdbcTemplate namedParameterJdbcTemplate;

     @InjectMocks
     PersonDAOImpl personDAOImpl;

     @BeforeEach
     void setUp() {
         MockitoAnnotations.initMocks(this);
     }

  @Test
  public void test() {

    when(namedParameterJdbcTemplate.query(ArgumentMatchers.anyString(),
                                          ArgumentMatchers.any(MemberExtractor.class))
                                         .thenReturn(//List<Members>);
    assertTrue(personDAOImpl.getAllMembers().size() > 0);

     }

 }