If you are using maven, you can add following dependency to your project.
01 02 03 04 05 06 | < dependency > < groupId >org.unitils</ groupId > < artifactId >unitils-inject</ artifactId > < version >3.4.2</ version > < scope >test</ scope > </ dependency > |
If you are not using maven you can download the unitils-with-dependencies.zip. The required jar, unitils-inject.jar, can be found in the unitils-inject folder, the required dependencies, in the unitils-inject/lib folder.
Unitils offers some utility methods to do injection of objects such as mocks into a target object (e.g. the tested object). There does not have to be any setter method, the fields can be private and can even be static.
The tested object is the actual instance that is being tested. The field of this tested object can be annotated with an TestedObject annotation. This will then become the default target for the injection. Unitils will automatically create an instance of the tested object if no instance is explicitly created in your test.
01 02 03 04 05 06 | public class MyServiceTest extends UnitilsJUnit4 { @TestedObject private MyService myService; } |
In this example we're writing a test for MyService. The test is unitils-enabled (it extends UnitilsJUnit4) so that unitils will handle the annotations. The field that holds the myService instance that is going to be used in the tests is marked as TestedObject. Unitils will automatically create a new MyService instance and will use it as default target for the injection annotations (see below). If you do not want unitils to create the instance, you can always create the instance yourself.
Note that you're not required to use the TestedObject annotation, all the injection methods and annotations offer the possibility to explicitly specify the target object.
01 02 03 04 05 06 07 08 09 | public class MyServiceTest extends UnitilsJUnit4 { @TestedObject private MyService myService; @InjectInto (property = "myDaoField" ) private MyDao myDao; } |
This will inject the myDao value into a field named myDaoField of the tested object, myService. Unitils injects the value directly in the field, there does not have to be a setter and the field can be private. The value for the attribute property of @Inject can be an arbitrary OGNL expression.
Instead of using a tested object, you can also specify the target object explicitly:
01 02 03 04 05 06 07 08 | public class MyServiceTest extends UnitilsJUnit4 { private MyService myService; @InjectInto (target = "myService" , property = "myDaoField" ) private MyDao myDao; } |
01 02 03 04 05 06 07 08 09 | public class MyServiceTest extends UnitilsJUnit4 { @TestedObject private MyService myService; @InjectIntoByType private MyDao myDao; } |
This will inject the myDao value into a field of type MyDao of the tested object, myService. There is no need to name the actual field, unitils will look for the best matching field type. If there are multiple possible targets, an exception will be raised. You will then have to use the InjectInto and explicitly name the property instead.
As with the InjectInto annotation you can also specify the target object explicitly:
01 02 03 04 05 06 07 08 | public class MyServiceTest extends UnitilsJUnit4 { private MyService myService; @InjectIntoByType (target = "myService" ) private MyDao myDao; } |
01 02 03 04 05 06 | public class MyServiceTest extends UnitilsJUnit4 { @InjectIntoStatic (target = MyService. class , property = "myDaoSingleton" ) private MyDao myDao; } |
This will inject the myDao value into the static myDaoSingleton field of the MyService class. After the test the value of the field will automatically be reset to its old value. This avoids that subsequent tests use the value that was set by this tests (it's a static field).
Following restores actions are possible:
The restore action can be specified in the annotation.
01 02 03 04 05 06 07 08 | @InjectIntoStatic (target = MyService. class , property = "myDaoSingleton" , restore = OLD_VALUE) private MyDao myDao1; @InjectIntoStatic (target = MyService. class , property = "myDaoSingleton" , restore = NO_RESTORE) private MyDao myDao2; @InjectIntoStatic (target = MyService. class , property = "myDaoSingleton" , restore = NULL_OR_0_VALUE) private MyDao myDao3; |
If no restore action is specified, the default, old value, will be used. This default is configurable by setting following property:
01 02 | # The default restore behavior. Possible values: old_value, no_restore or null_or_0_value InjectModule.InjectIntoStatic.Restore.default =old_value |
In this example, we create a mock of type MyDao and inject it in the tested object MyService. Because the test does not create the myService instance, it will be automatically created by unitils.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 | public class MyServiceInjectTest extends UnitilsJUnit4 { @TestedObject private MyService myService; @InjectIntoByType private Mock<MyDao> myDaoMock; @Test public void testMethod() { // define behavior myDaoMock.returns( "something" ).getSomething(); // do the actual test boolean result = myService.doService(); // assert results and invocations assertTrue(result); myDaoMock.assertInvoked().storeSomething( "something" ); } } |