我在Spring MVC應用程序中遇到了一些單元測試問題。在完全披露的情況下,鑑於我從頭開始編寫測試套件的經驗不足,我錯誤地設計了我的單元測試。PreparedStatement.execute()在Spring單元測試中掛起
我現在設計的方式是,例如,測試用戶服務,測試套件使用原始SQL語句來驗證數據是否正確插入/檢索/更新。我遇到的問題是,在執行第一個預處理語句之後,後續語句掛在方法上。測試的結果呢?「鎖等待超時超標;嘗試重新啓動交易」
基於什麼我在線閱讀,這很可能是一個事務的管理問題,並有人不釋放鎖,但我我不知道如何做到最好,甚至在哪裏做。
一些相關的代碼如下,讓我知道是否有更多的代碼是必要的。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/applicationContext-base.xml", "/application-security.xml"})
@TransactionConfiguration(transactionManager="txManager")
@Transactional
public class TestUserService {
@Autowired
UsersService userService;
@Autowired
DataSource dataSource;
Connection connection;
@Before
public void setup() throws Exception{
connection = dataSource.getConnection();
}
@Test
public void testCreateUser() throws Exception{
Collection<GrantedAuthorityImpl> auths = new ArrayList<GrantedAuthorityImpl>();
auths.add(new GrantedAuthorityImpl(SecurityConstants.ROLE_USER));
User user = new User("testUser", "testpassword", true, true, true, true, auths, "salt");
User tmp = userService.createUser(user);
PreparedStatement ps = connection.prepareStatement("select id, username, password, created, enabled, salt from users where id = ?");
PreparedStatement ps2 = connection.prepareStatement("select user, authority from user_authorities where user = ?");
ps.setLong(1, tmp.getId());
ps2.setLong(1, tmp.getId());
ResultSet rs = ps.executeQuery();
ResultSet rs2 = ps2.executeQuery();
rs.first();
rs2.first();
Collection<GrantedAuthorityImpl> authsFromDb = new ArrayList<GrantedAuthorityImpl>();
rs.first();
do{
authsFromDb.add(new GrantedAuthorityImpl(rs2.getString("authority")));
}while(rs2.next());
User tmp2 = new User(rs.getString("username"), rs.getString("password"), rs.getBoolean("enabled"), true, true, true, authsFromDb, rs.getString("salt"));
Assert.assertEquals(tmp.getUsername(), tmp2.getUsername());
Assert.assertEquals(tmp.getId(), tmp2.getId());
Assert.assertEquals(tmp.getPassword(), tmp2.getPassword());
Assert.assertEquals(tmp.getSalt(), tmp2.getSalt());
Assert.assertEquals(tmp.getAuthorities(), tmp2.getAuthorities());
Assert.assertEquals(tmp.isEnabled(), tmp2.isEnabled());
}
@Test
public void testSaveUser() throws Exception{
long createdTime = System.currentTimeMillis();
String insertionQry = "insert into users (username, password, created, enabled, salt) values ('chris', 'somepassword'," + createdTime + ",1,'salt')";
PreparedStatement ps = connection.prepareStatement(insertionQry, Statement.RETURN_GENERATED_KEYS);
ps.execute();
ResultSet rs = ps.getGeneratedKeys();
rs.first();
long id = rs.getLong(1);
Assert.assertEquals(true, id != 0);
String loadQry = "select id, username, password, created, enabled, salt from users where id = " + id;
ps = connection.prepareStatement(loadQry);
rs = ps.executeQuery();
rs.first();
Assert.assertEquals(rs.getString("username"), "chris");
Assert.assertEquals(rs.getString("password"), "somepassword");
Assert.assertEquals(rs.getBoolean("enabled"), true);
Assert.assertEquals(rs.getString("salt"), "salt");
User user = new User("second_username", "newpassword", false, true, true, true, AuthorityUtils.NO_AUTHORITIES, "secondsalt");
user.setId(rs.getLong("id"));
userService.saveUser(user);
ps = connection.prepareStatement(loadQry);
rs = ps.executeQuery();
rs.first();
Assert.assertEquals(rs.getString("username"), "second_username");
Assert.assertEquals(rs.getString("password"), "newpassword");
Assert.assertEquals(rs.getBoolean("enabled"), false);
Assert.assertEquals(rs.getString("salt"), "secondsalt");
}
啊很有意思,我會檢查一下。其中一件事我從未在文檔中看到過...... –
哇,就是這樣。我真的希望這是他們在文檔中做得更清楚的事情...... –