我正在为应用程序创建新的单元测试,但我陷入困境,因为
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。
感谢@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);
}