我必须编写一些单元测试,现在我有一些,但我决定发布一个主题因为我不知道测试是否正确,尽管它们在Eclipse中运行并且EclEmma显示测试涵盖测试代码(突出显示绿色)。在一个句子中,单元测试是正确的。
我将测试的方法
@Service
@Configurable
public class UserManager {
@Autowired
private UserManagerDao umDao;
public long getUserId(String email) throws Exception {
String[] partsOfEmail = email.split("@");
return umDao.getUserId(partsOfEmail [0], partsOfEmail [1]);
}
}
Dao class
public class UserManagerDao extends JdbcDaoSupport {
@Autowired
private MessageSourceAccessor msa;
public long getUserId(String userName, String domain) throws Exception {
String sql = msa.getMessage("sql.select.user_id");
Object[] params = new Object[] { userName, domain };
List<Long> result = getJdbcTemplate().queryForList(sql, params, Long.class);
if (result.size() > 0) {
return result.get(0);
}
return 0;
}
测试
@RunWith(MockitoJUnitRunner.class)
public class UserManagerTest {
@Mock
UserManagerDao umDao;
private String email = "email@email.com";
@Test
public void testGetPassportUserId() throws Exception {
um.getPassportUserId(email);
}
}
答案 0 :(得分:1)
快速回答是'不完全'。
您的代码似乎不完整 - 例如,在您的测试中,您调用了um.getPassportUserId(email)
,但未声明um
(我假设它是UserManager
并以某种方式注入?) ,我没有看到名为getPassportUserId
的方法。忽略这些点,我能看到的最大问题是你的测试中没有断言;你没有检查方法是否会返回你期望的结果。
测试的一个常见模式是'Given,When,Then',这意味着你的测试应该以'给定'部分开始 - 也就是说,它设置模拟以返回你需要的任何东西,然后'当'应该是你的方法调用'然后'检查方法调用的结果。
因此,对于您的示例,在Pseudocode中,我期望类似于:
@Test
public void testGetPassportUserId() throws Exception {
// Given...
String username = "foo";
String domain = "bar";
long expectedId = 1L;
// Use Mockito to tell the mocked umDao to return expectedId when you request "foo@bar"
// When...
long actualId = um.getPassportUserId(username + "@" + domain);
// Then...
// Use an assertion to ensure that actualId = expectedId
}
我故意让这个开放得很开心,因为你对如何设置模拟有很多正确答案(查看Mockito文档)以及更正确的断言方法(查看JUnit文档,以及Mockito和Hamcrest)。
另外,这是与代码覆盖工具相关的潜在缺陷的一个很好的例子。 Emma正在告诉你所有代码都已执行完全正确,因为它有,但是你无法知道执行是否正确,而没有在你的测试中执行某些断言,所以它给你一个错误安全感。