Java 单元测试因 KeyHolder 为空而失败

问题描述 投票:0回答:1

我正在为应用程序创建新的单元测试,但我陷入困境,因为

KeyHolder
没有返回有效的对象。

对于上下文,这是我的课程:

ScriptDao 类:

@Repository
public class ScriptDao extends DefaultDao {

    private static final Logger LOG = LoggerFactory.getLogger(ScriptDao.class);

    public Long save(ScriptModel script) {
        LOG.debug("saving script {}", script);

        String sql = "INSERT INTO " + DBTable.SCRIPT + " (script_type_id, hash, content) " +
                "VALUES(?, ?, ?)";

        List<Object> queryParams = new LinkedList<>();
        queryParams.add(script.getScriptType());
        queryParams.add(script.getHash());
        queryParams.add(script.getContent());

        KeyHolder keyHolder = save(sql, queryParams);

        return keyHolder.getKey() != null ? keyHolder.getKey().longValue() : null;
    }
}

默认Dao类:

@Repository
public class DefaultDao {

    @Autowired
    protected ObjectMapper jacksonObjectMapper;

    @Autowired
    protected JdbcTemplate jdbcTemplate;

    public KeyHolder save(String sql, List queryParams) {
        Object[] parameters = queryParams.toArray();
        printSQL(sql);
        printParams(queryParams);
        KeyHolder keyHolder = new GeneratedKeyHolder();
        int rowAffected = jdbcTemplate.update(getPreparedStatementCreator(sql, parameters), keyHolder);
        getLogger().debug("operation successfully completed on {} rows", rowAffected);
        return keyHolder;
    }
}

测试用例:

@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
public class ScriptDaoTest {

    @InjectMocks
    private ScriptDao scriptDao;

    @Mock
    private JdbcTemplate jdbcTemplate;

    @Mock
    private SqlRowSet sqlRowSet;

    @Mock
    private DefaultDao defaultDao;

    @Test
    void testSaveMethod() {
        ScriptModel script = new ScriptModel();
        script.setScriptType(1);
        script.setHash("hash123");
        script.setContent("content");

        Map<String, Object> keyMap = new HashMap<String, Object>();
        keyMap.put("", 1L);

        KeyHolder keyHolder = new GeneratedKeyHolder();
        List<Map<String, Object>> generatedKeys = keyHolder.getKeyList();
        generatedKeys.clear();
        generatedKeys.add(keyMap);

        when(defaultDao.save(anyString(), anyList())).thenReturn(keyHolder);

        Long result = scriptDao.save(script);

        assertEquals(1L, result);
    }
}

当我运行单元测试时,它在assertEquals 中失败,并显示以下消息:

org.opentest4j.AssertionFailedError: 
Expected :1
Actual   :null
<Click to see difference>


    at org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:151)
    at org.junit.jupiter.api.AssertionFailureBuilder.buildAndThrow(AssertionFailureBuilder.java:132)
    at org.junit.jupiter.api.AssertEquals.failNotEqual(AssertEquals.java:197)
    at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:182)
    at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:177)
    at org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:639)
    at com.xxxxxxx.daos.ScriptDaoTest.testSaveMethod(ScriptDaoTest.java:62)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at java.util.ArrayList.forEach(ArrayList.java:1259)
    at java.util.ArrayList.forEach(ArrayList.java:1259)


Process finished with exit code -1

我在测试用例中添加了一些日志消息,我可以看到

keyHolder
具有正确的值,但
defaultDao.save()
似乎没有使用单元测试中定义的
keyHolder

我预计我的

assertEquals
将是 true,因为单元测试中的
KeyHolder
被硬编码为 1。

java junit mockito junit5
1个回答
0
投票

感谢@Turing85,在您发表评论后,我更改了以下单元测试,现在它可以工作了!

@Test
void testSaveMethod() {
    ScriptModel script = new ScriptModel();
    script.setScriptType(1);
    script.setHash("hash123");
    script.setContent("content");

    doAnswer(invocation -> {
        KeyHolder keyHolder = invocation.getArgument(1);
        Map<String, Object> keyMap = new HashMap<String, Object>();
        keyMap.put("", 1L);
        List<Map<String, Object>> generatedKeys = keyHolder.getKeyList();
        generatedKeys.clear();
        generatedKeys.add(keyMap);
        return 1;
    }).when(jdbcTemplate).update(any(), any(KeyHolder.class));

    Long result = scriptDao.save(script);

    assertEquals(1L, result);
}
© www.soinside.com 2019 - 2024. All rights reserved.