1

I have two classes, Parent and Child, and want to unit test some methods in the Child class using Mockito.

public abstract class Parent {

  @Resource Service service;

}
@Service // spring service
public class Child extends Parent {

   private AnotherService anotherService;

   @Autowired
   Child(AnotherService anotherService) {
      this.anotherService = anotherService;
   }

   public boolean someMethod() {
   }
}

My test class looks like below:

@RunWith(MockitoJUnitRunner.class)
public class ChildTest {
   @Mock
   Service service;

   @Mock
   AnotherService anotherService;

   @InejctMocks
   Child classToTest;

   @Test
   public void testSomething() {
      assertTrue(classToTest.someMethod());
   }
}

And the issue I am facing is that anotherService is being mocked properly but service is null. Can someone please tell me how to successfully mock both of the services (dependencies) in my test class?

Compzets
  • 11
  • 5
  • 2
    how do you instantiate the Child? How you set/inejct the dependencies? – Maciej Kowalski Jul 26 '19 at 10:35
  • This is nothing to do with a parent/child structure really. Rather, it's related to you using field injection, rather than constructor injection. – Michael Jul 26 '19 at 10:37
  • @MaciejKowalski It is a Spring bean. Have edited the question as well. Thanks for pointing this out. – Compzets Jul 26 '19 at 10:37
  • I am more interested how you do it in the test. Do you use InjectMocks? – Maciej Kowalski Jul 26 '19 at 10:39
  • @Michael can you pl elaborate a bit? The dependencies in the child class use constructor injection and not field injection. – Compzets Jul 26 '19 at 10:40
  • @Compzets Yeah exactly. In the child class... Give the parent a constructor and pass an argument up. – Michael Jul 26 '19 at 10:40
  • @Michael how is this a duplicate to the question you linked? The solution there doesn't work for me as I have mentioned in the post. I have used the `@Mock` annotation but I am not able to mock `service`. Am I missing something? – Compzets Jul 26 '19 at 10:48
  • https://ideone.com/6Cb4si – Michael Jul 26 '19 at 10:48
  • By "as I have mentioned in the post" I meant I have used the proper annotation as mentioned in the other question but still wasn't getting the desired result. Regarding your solution, I am afraid I can't modify the source code. I have tried it before posting the question and it works but I was looking for a solution without the need to modify the source. – Compzets Jul 26 '19 at 10:59

2 Answers2

0

inside the test, class add this and try

@Before
public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);
}
MangduYogii
  • 935
  • 10
  • 24
0

If you use Spring:

   @SpringBooTest
   @RunWith(SpringRunner.class)
   @MockBean(Resource.class)
   class TestClass{
        @Autowire
        private Resource resource;

        @Autowire
        private Service service;
        
        @Test
        public void test(){
           Mockito.when(resource).getSomething(Mockito.any(),Mockito.any()).thenThrow(new RuntimeException(""));

           service.doSomething();  
        }
    
   }

You can use Mockito:

// Or use MockitoAnnotations.initMocks(testClass); in before method instead rule
@RunWith(MockitoJUnitRunner.class) 
class TestClass{
     @Mock
     Resource resource;

     @InjectMocks 
     Service service;

     @Test
     public void test(){
           Mockito.when(resource).getSomething(Mockito.any(),Mockito.any()).thenThrow(new RuntimeException(""));

           service.doSomething();  
     }
}
Stanislav Serdiuk
  • 421
  • 1
  • 6
  • 21
  • Why @InjectMocks on service? I am not testing service but rather testing the class `Child`. – Compzets Jul 26 '19 at 13:47
  • @Compzets Just replase my resource to your service and my service to your classToTest. Is in your parent class service field equal null in test method? Or is it equal null in your classToTest. I suppose one is null in tested class. Because your `@Resource Service service` has never been initialized. – Stanislav Serdiuk Jul 27 '19 at 07:57
  • Syntax in this answer is invalid. This code does not compile. – 8bitjunkie Sep 16 '20 at 23:22