Reputation: 1468
I want to write unit test for below scala class. In the below implementation, QueryConfig is final case class.
class RampGenerator {
def createProfile(queryConfig: QueryConfig): String = {
new BaseQuery(queryConfig).pushToService().getId
}
}
The unit test I have written is this
@RunWith(classOf[JUnitRunner])
class RampGeneratorTest extends FlatSpec with Matchers {
"createProfile" must "succeed" in {
val rampGenerator = new RampGenerator()
val queryConfig = QueryConfig("name", "account", “role")
val baseQuery = mock(classOf[BaseQuery])
val profile = mock(classOf[Profile])
when(new BaseQuery(queryConfig)).thenReturn(baseQuery)
when(baseQuery.pushToService()).thenReturn(profile)
when(profile.getId).thenReturn("1234")
val id = rampGenerator.createProfile(queryConfig)
assert(id.equals("1234"))
}
}
Currently it gives below exception, which is expected, since I don't have mocked class used in when. How do I mock the new instance creation?
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
Upvotes: 0
Views: 2484
Reputation: 26951
There are two options:
A bit more on the second option - this is actually a testing technique that helps in a variety of situations (a couple of examples: yours, creating akka actors and asserting on hierarchies) - so it might be useful to just have it in the "toolbox".
In your case it'll look something like this:
class RampGenerator(queryFactory: QueryFactory) {
def createProfile(queryConfig: QueryConfig) = queryFactory.buildQuery(queryConfig).pushToService().getId()
}
class QueryFactory() {
def buildQuery(queryConfig: QueryConfig): BaseQuery = ...
}
@RunWith(classOf[JUnitRunner])
class RampGeneratorTest extends FlatSpec with Matchers {
"createProfile" must "succeed" in {
val rampGenerator = new RampGenerator()
val queryConfig = QueryConfig("name", "account", “role")
val queryFactory = mock(classOf[QueryFactory])
val profile = mock(classOf[Profile])
val baseQuery = mock(classOf[BaseQuery])
when(queryFactory.buildQuery(queryConfig)).thenReturn(baseQuery)
when(baseQuery.pushToService()).thenReturn(profile)
when(profile.getId).thenReturn("1234")
val id = rampGenerator.createProfile(queryConfig)
assert(id.equals("1234"))
}
}
Please note query factory does not have to be a separate factory class/hierarchy of classes (and certainly does not require something as heavyweight as abstract factory pattern - although you can use it). In particular, my initial version was just using queryFactory: QueryConfig => BaseQuery
function, but mockito cannot mock functions...
If you prefer to inject factory method directly (via function), Scalamock has support for mocking functions
Upvotes: 1