Injecting a mock object into the object to be tested, declared as a field in the test, does not work using Mockito?

I have a class and I inject a proxy server into my service.

Service service { private ServiceProxy proxy; public Service(ServiceProxy proxy) { this.proxy = proxy; } } 

Test for him:

 ServiceTest { @Mock ServiceProxy mockProxy; Service service = new Service(mockProxy); } 

If I initialize my class this way, I always get NPE when I want to use the service object. Why is Mockito doing this? What is an easy way to do this and not declare it in all tests?

+4
source share
2 answers

If you are using Mockito version 1.9.0 or later, the best way to achieve what you want is as follows:

 @RunWith(MockitoJUnitRunner.class) public class ServiceTest { @Mock private ServiceProxy proxy; @InjectMocks private Service service; @Test public void test() { assertNotNull(service); assertNotNull(proxy); } } 

First of all, this is the @RunWith(MockitoJUnitRunner.class) , which will cause the @Mock and @InjectMocks annotations to work automatically without any explicit initialization. Secondly, starting with the annotation Mockito 1.9.0 @InjectMocks, you can use the constructor installation mechanism, which is the best option for your class of service.

Other options for @InjectMocks are Setter injection and field injection (see BTW docs ), but you don't need a constructor with no arguments to use them.

So, to summarize - your code cannot work, because:

  • you are not using MockitoJUnitRunner or MockitoAnnotations.initMocks (this), so the @Mock annotation is not affected.
  • even if the above was completed, your example will fail because mockProxy will be initialized after the test is created and your service will be initialized during the assembly of the test class, so it gets a null mockProxy reference.

If for some reason you do not want to use @InjectMocks, the only way is to create your service object inside the body of the test method or in the setBufore @Before method.

+4
source

Write your test class that will initialize the Service using the ServiceProxy layout:

 class ServiceTest { @Mock ServiceProxy mockProxy; //This will inject the "ServiceProxy" mock into your "Service" instance. @InjectMocks Service service = new Service(mockProxy); @Before public void init() { //This will initialize the annotated mocks MockitoAnnotations.initMocks(this); } @Test public void test() { ... } } 
+1
source

Source: https://habr.com/ru/post/957062/


All Articles