1
votes

I have a simple User class that has first name, last name and email I've marked the email like this

@Column(name="email",unique=true)
@NotNull
@Email
private String email;

I'm running the following junit test but its failing

@Test(expected = org.hibernate.exception.ConstraintViolationException.class)  
public void testUniqueEmail() throws DaoException{
    User uri = new User("uri","naor","[email protected]");
    userDao.saveUser(uri);
    //Session session = sessionFactory.getCurrentSession();
    //session.save(uri);
    //session.flush();  
    User clone = new User("clone","wars","[email protected]");
    userDao.saveUser(clone);
    //session.save(clone);
    //session.flush();
}

I've tried using the userDao or using the session directly so I can flush either way junit fails saying

java.lang.AssertionError: Expected exception: org.hibernate.exception.ConstraintViolationException at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:32) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:232) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:175) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) org.hibernate.exception.ConstraintViolationException: could not execute statement at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:72) at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49) at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126) at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112) at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:190) at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:62) at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3124) at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3587) at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:103)

How can I make this test pass?

*EDIT It seems that my question was not very clear my model has a field called email which is unique, so I expect that when I insert an object that has the same email, the DB should reject it.

To test it, I made a simple test that persist an object with email "[email protected]" and than created another object with the same email. The problem is with JUNIT as the test fails due to ConstraintViolationException as expected yet the test is RED.

3
userDao is not throwing your expected ConstraintViolationExceptionikumen
if you remove the 'excepted' from the @Test and then run the test, then it fails because of ConstraintViolationException, which is the expected since im inserting two identical valuesnaoru

3 Answers

1
votes

ok so i managed to pass the test here is the code snippet the key is to catch this exception, clear the session and then rethrow it

@Test(expected = org.hibernate.exception.ConstraintViolationException.class)  
public void testUniqueEmail() throws DaoException{
    User uri = new User("uri","naor","[email protected]");
    userDao.saveUser(uri);
    User clone = new User("clone","wars","[email protected]");
    userDao.saveUser(clone);
    try{
        sessionFactory.getCurrentSession().flush();
    }catch(org.hibernate.exception.ConstraintViolationException ex){
        sessionFactory.getCurrentSession().clear();
        SQLException ex1= new SQLException();
        throw new ConstraintViolationException("Could not insert",ex1,"what else");
    }
}

hope it helps somebody

0
votes

I had the same problem. Catching org.hibernate.exception.ConstraintViolationException would catch nothing, eventhough all tests failed because this exception had been thrown - at least that's what the IDE told at the first glance.

What helped me in my case was to catch javax.persistence.PersistenceException instead.

enter image description here

-2
votes

You're failing because you've told junit to expect a ConstraintViolationException and your the methods called in your test aren't throwing it. The test itself has some problems but the above is the reason it is failing ... look at the first line of the stacktrace.