【问题标题】:NullPointerException on mockito spring's NamedParameterJdbcTemplatemockito spring 的 NamedParameterJdbcTemplate 上的 NullPointerException
【发布时间】:2020-04-28 08:19:53
【问题描述】:

我有一个 DAO 类,我正在尝试编写测试用例

这里是修改后的可重现代码

我要测试的 DAO 类


@Component
public class SomeDAO {

    @Autowired
    private NamedParameterJdbcTemplate namedParameterJdbcTemplate;


    public boolean dataInTable(String id) {
        String sql = "SELECT COUNT(*) " +
                "FROM table1" +
                "WHERE id =:id";



        MapSqlParameterSource sqlParms = new MapSqlParameterSource();
        sqlParms.addValue("id", id

        try {
            int count = namedParameterJdbcTemplate.queryForObject(sql, sqlParms, Integer.class);
            return (count > 0) ? true : false;

        } catch (Exception e) {
            log.error("Error checking existence of id : " + id);
            throw e;
        }
    }

}

当我运行测试时,它会抛出一个 NullPointer

int count = namedParameterJdbcTemplate.queryForObject(sql, sqlParms, Integer.class);

所以我相信 mockito 不会在何时返回值,然后返回

我搜索了堆栈溢出,看起来我应该可以工作,但我得到了 NullPointerException。

我也尝试过使用与 dao 类相同的 sql 字符串和 mapObject 值,而不是 anyString() 和 anyMap()

但也没有用

测试用例

@RunWith(MockitoJUnitRunner.class)
public class SomeDAOTest {

    @InjectMocks
    SomeDAO someDao

    @Mock
    NamedParameterJdbcTemplate namedParameterJdbcTemplate;


    @Before
    public void init() {
        MockitoAnnotations.initMocks(this);

    }

    @Test
    public void TestdataInTable(){

        //
        when(namedParameterJdbcTemplate.queryForObject(anyString(), anyMap(),eq(Integer.class))).thenReturn(1);
        assertEquals( true,someDao.dataInTable("123456"));
    }

}

【问题讨论】:

    标签: spring-boot junit mockito jdbctemplate


    【解决方案1】:

    试试这个,

    @Test
      public void TestdataInTable() {
    
        Mockito.when(namedParameterJdbcTemplate.queryForObject(Mockito.anyString(),
            Mockito.any(SqlParameterSource.class), Mockito.eq(Integer.class))).thenReturn(1);
        assertEquals(true, someDao.dataInTable("123456"));
      }
    
    1. queryForObject() 中的第二个参数是SqlParameterSource 类型,它不是直接映射。所以应该是,Mockito.any(SqlParameterSource.class)。

    您的代码的当前版本在控制台中显示警告,这是调试问题的最佳方式。

    [MockitoHint] TestDao.TestdataInTable (see javadoc for MockitoHint):
    [MockitoHint] 1. Unused... -> at TestDao.TestdataInTable(TestDao.java:33)
    [MockitoHint]  ...args ok? -> at SomeDao.dataInTable(SomeDao.java:26)
    

    【讨论】:

    • 在这个答案之上:你不需要MockitoAnnotations.initMocks()MockitoJUnitRunner - 只保留其中一个。另外:SqlParameterSource 根本不是地图。这个方法只有2个重载版本,mock了错误的重载
    • 这行得通!。但我无法投票或接受答案,因为我没有足够的声誉
    【解决方案2】:

    添加此内容可能会对某人有所帮助:

    我遇到了类似的问题,但原因却大不相同。 我不仅在NamedParameterJdbcTemplate 上得到空指针异常,它用@Mock 注释,而且在@InjectMocks 上。

    原来我使用的是 Junit 5。上述解决方案适用于 Junit 4。要使 Mockito 使用 Junit 5,需要额外的注释。还要确保删除@RunWith(MockitoJUnitRunner.class),因为这会导致失败。请改用@ExtendWith(MockitoExtension.class

    这是一个例子:

    @ExtendWith(MockitoExtension.class) 
    public class SomeDAOTest {
    
    @InjectMocks
    SomeDAO someDao
    
    @Mock
    NamedParameterJdbcTemplate namedParameterJdbcTemplate;
    

    【讨论】:

      猜你喜欢
      • 2021-12-14
      • 1970-01-01
      • 2017-08-21
      • 2016-10-27
      • 1970-01-01
      • 2014-07-27
      • 1970-01-01
      • 1970-01-01
      • 2015-01-19
      相关资源
      最近更新 更多