Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Injecting a String property with @InjectMocks

I have a Spring MVC @Controller with this constructor:

@Autowired public AbcController(XyzService xyzService, @Value("${my.property}") String myProperty) {/*...*/} 

I want to write a standalone unit test for this Controller:

@RunWith(MockitoJUnitRunner.class) public class AbcControllerTest {      @Mock     private XyzService mockXyzService;      private String myProperty = "my property value";      @InjectMocks     private AbcController controllerUnderTest;      /* tests */ } 

Is there any way to get @InjectMocks to inject my String property? I know I can't mock a String since it's immutable, but can I just inject a normal String here?

@InjectMocks injects a null by default in this case. @Mock understandably throws an exception if I put it on myProperty. Is there another annotation I've missed that just means "inject this exact object rather than a Mock of it"?

like image 491
Sam Jones Avatar asked Mar 18 '16 12:03

Sam Jones


People also ask

What is the use of @InjectMocks annotation?

@InjectMocks is the Mockito Annotation. It allows you to mark a field on which an injection is to be performed. Injection allows you to, Enable shorthand mock and spy injections.

Can we use @SPY and @InjectMocks together?

@Spy and @InjectMocks cannot be used well together (see Google Code issue #489 and GitHub issue #169), and for what they do it is not clear or common that they should be used together at all. In well-written Mockito usage, you generally should not even want to apply them to the same object.

Why you should not use InjectMocks?

You shouldn't use InjectMocks to deal with injecting private fields (err..or at all) , because this kind of Dependency Injection is evil – and signals you should change your design.

How do you mock injected objects?

Mockito @InjectMocks annotations allow us to inject mocked dependencies in the annotated class mocked object. This is useful when we have external dependencies in the class we want to mock. We can specify the mock objects to be injected using @Mock or @Spy annotations.


1 Answers

You can't do this with Mockito, but Apache Commons actually has a way to do this using one of its built in utilities. You can put this in a function in JUnit that is run after Mockito injects the rest of the mocks but before your test cases run, like this:

@InjectMocks MyClass myClass;  @Before public void before() throws Exception {     FieldUtils.writeField(myClass, "fieldName", fieldValue, true); } 
like image 116
Jacob Beasley Avatar answered Sep 19 '22 12:09

Jacob Beasley