I am writing an integration test between my JPA layer and the database to check the SQL I've written is correct. The real database is Oracle, unfortunately down to reasons out my control my test database has to be Derby so naturally there are some differences. For example my JPA class has the following SQL String constant
private static final String QUERY = "Select * from Users where regexp_like(user_code, '^SS(B)?N')";
Because Derby doesn't support regexp_like
I am using JMockits Deencapsulation.setField
to change the SQL on the fly. eg.
@Test
public void testMyDaoFind() {
new Expectations() {
{
Deencapsulation.setField(MyClass.class, "QUERY", "Select * from Users");
}
};
dao.findUsers();
}
Now ignoring the fact that this isn't a good test as it's not testing the actual query that will be running on the real database (this is purely to satisfy my curiousity as to what is going on), I am getting a SQL exception error from Eclipselink/Derby complaining about regexp_like is not recognized as a function or a procedure.
If I place a break point on the line in the DAO that attempts to get the result list, I can see from a new watch that
JMockit has substituted the query correctly
getResultList() returns the data I'm expecting to see
If however I let the test run all the way through then I get the afformentioned exception?!
Strings in Java are not handled the way you are thinking. The Java source compiler replaces reads from fields holding string literals with the fixed "address" where the string is stored (in the class' constant pool); the field is not read anymore at runtime. So, even if JMockit replaces the string reference stored in the field, it makes no difference as that reference isn't seen by the client code using the field.
(BTW, why is the test putting the call to Deencapsulatin.setField
inside an expectation block? Such blocks are only meant for recording expectations...)
Bottom line, there is no way to achieve what you're trying to. Instead, either use an Oracle database for integration testing, or make all SQL code portable, avoiding RDBMS-specific functions such as regexp_like
.