Reputation: 2290
I have a service class written in groovy, as follows:
import groovy.sql.Sql
import javax.sql.DataSource
import java.sql.SQLException
class DatabaseService {
DataSource dataSource;
void registerUser(User user) {
try {
def sql = new Sql(dataSource);
sql.call("{call regUser(?)}", [user.name])
} catch (SQLException e) {
log.error("unable to register the user", e)
throw e;
}
}
}
What I want to do here, is Mock the sql.call method, to throw an SQLException. Writing an integration test to do this, at this time, is not possible.
Here is what I have so far:
void "test registerDeveloper exception handling"() {
String expectedErrorMsg = "exception from test"
DataSource mockedSource = Mock(DataSource)
User user = new User(name: "joe")
Sql mockedSql = Mock(Sql)
DatabaseService databaseService = new DatabaseService(dataSource:mockedSource)
given:
mockedSql.call(_,_) << {throw new SQLException()}
when:
databaseService.registerUser(user)
then:
def exception = thrown(SQLException)
exception.message == expectedErrorMsg
}
With the above code, I get this error:
groovy.lang.MissingMethodException: No signature of method: java.lang.Integer.leftShift() is applicable for argument types: (UcopRip.DatabaseServiceSpec$__spock_feature_0_0_closure1) values: [UcopRip.DatabaseServiceSpec$__spock_feature_0_0_closure1@77049094] Possible solutions: leftShift(java.lang.Number), rightShift(java.lang.Number)
If I change << to >>, I get this error: Expected exception of type 'java.sql.SQLException', but got 'java.lang.NullPointerException', poiting to sql.call line in the DatabaseService class.
Does anyone have an idea what I am doing wrong? I am certainly new to testing with SPOCK, but cannot seem to find anywhere online where people are mocking SQL methods.
Upvotes: 1
Views: 2907
Reputation: 11022
Interaction should be in a when clause, and use >>
Moreover 'Sql' is a class, and is created in your service : you can't mock it really easily. it's more simple to test this kind of things with an in-memory db like hsqldb, but you can mock the connection and preparedstatement (it's ugly)
void "test registerDeveloper exception handling"() {
given:
String expectedErrorMsg = "exception from test"
DataSource mockedSource = Mock(DataSource)
def user = new User(name: "joe")
def databaseService = new DatabaseService(dataSource:mockedSource)
when:
databaseService.registerUser(user)
then:
1* mockedSource.getConnection() >> {throw new SQLException(expectedErrorMsg)}
and:
def exception = thrown(SQLException)
exception.message == expectedErrorMsg
}
Upvotes: 1