Reputation: 569
I have begun to use ScalaTest to test my Java code and I like it (I've read the "Testing in Scala" book).
Recently I've been trying to test some java Spring code that contain fields which are marked private
and @Autowired
. There are no setter methods for these fields.
I realise that I could easily test them using JUnit + Mockito using the annotations @InjectMocks
and @Mock
, however, I would like to test them using ScalaTest and a mocking framework (such as Mockito or ScalaMock).
My question: Can Scalatest + Mockito be used to mock out private fields or do these frameworks require that my java classes have a public
setter method defined for my private
+ @Autowired
fields?
Upvotes: 0
Views: 1373
Reputation: 438
You can do it with InjectMocks. Here's a working example using ScalaTest and Mockito to test a class containing @Autowired members:
import org.mockito.{MockitoAnnotations, InjectMocks, Mock}
import org.scalatest.{FunSpec, BeforeAndAfter}
import org.scalatest.Matchers._
import org.mockito.Mockito._
import org.springframework.beans.factory.annotation.Autowired
class InjectMocksSpec extends FunSpec with BeforeAndAfter {
@Mock
var paramMock: MockedClass = null
@InjectMocks
var testClass = new TestClass()
describe("InjectMocks") {
it("should inject mock for Autowired field") {
MockitoAnnotations.initMocks(this)
when(paramMock.get).thenReturn("bar")
testClass.test should be("bar")
verify(paramMock, times(1)).get
}
}
}
class MockedClass {
def get: String = {
"foo"
}
}
class TestClass {
@Autowired
var param: MockedClass = null
def test: String = {
param.get
}
}
Upvotes: 3
Reputation: 1
You can use @Mock
annotation in import org.mockito.MockitoAnnotations.Mock
@Mock
private var someDao:SomeDao =_
this works but is not advisable to use. It is also being deprecated
Upvotes: 0
Reputation: 106490
In my experience, it's been far better to add setters to those autowired beans. Otherwise, the only way you're going to inject the behavior you want is through a convoluted reflection process, which only serves to complicate matters.
To make it explicit that the setters aren't to be used outside of test, you can do a couple of things:
Mark them as package-private
void setDao(final Dao dao) {
this.dao = dao;
}
Annotate them with @VisibleForTesting
from Guava
Alternatively, it may be a good time to revisit the autowiring scheme; it can become very unwieldy if you have a lot of beans that you're automatically wiring in.
Upvotes: 0