2

I have something like this

@Component
public class TestController {

    @Autowired
    private TestService testService;

    public String getSomething(String parameter1) {
        return testService.fetchSomething(parameter1);
    }
}

And I am covering it with tests and have the following problem:

@RunWith(MockitoJUnitRunner.class)
public class TestControllerTest {
    private static TestService testService = mock(TestService.class);
    @InjectMocks
    private static TestController testController = new TestController();

    ....
}

These fields are static because I need them for @ClassRule.

The problem is that in this case injection doesn't work, and testService is null in testController.

Is it possible to provide injection into static object (without constructor creation in Controller)? Or maybe there is another workaround for this?

The question is not about mocking static methods, but injecting mocks into static objects Will appreciate any advice, thanks.

me1111
  • 1,127
  • 3
  • 26
  • 38
  • Possible duplicate of [Mocking static methods with Mockito](http://stackoverflow.com/questions/21105403/mocking-static-methods-with-mockito) – Dominik Sandjaja Nov 17 '15 at 11:34
  • @DaDaDom, this is not about mocking static methods, but injecting mocks into static objects – me1111 Nov 17 '15 at 11:37
  • 2
    I think it would be better to do a proper dependency injection via constructor so you can have it declared as final in `TestController`. `TestController testController = new TestController(testService)` and you don't need annotation at all. – Jaroslaw Pawlak Nov 17 '15 at 11:40
  • @Jaroslaw Pawlak, that's what I think too, but I need a solution, which won't affect the logic, only tests. I have suspicious that this is impossible – me1111 Nov 17 '15 at 11:42
  • 2
    @me1111 You can do this in static block as mlk suggested. If you don't have setters and fields are private, you can use reflection API, but it's rather ugly solution as you lose compile-time safety. – Jaroslaw Pawlak Nov 17 '15 at 11:44

1 Answers1

2

I think you would have to use a static block.

@RunWith(MockitoJUnitRunner.class)
public class TestControllerTest {
    private static TestService testService = mock(TestService.class);

    private static TestController testController ;
    static {
       testController = new TestController(testService);
    }
    ....
}

As you use magically injection you have have to use some reflection, or change to constructor injection. Life is better that way anyway.

Michael Lloyd Lee mlk
  • 14,561
  • 3
  • 44
  • 81
  • thanks for response, mlk. But TestController doesn't have setters, maybe there is an another way without changing the main logic? – me1111 Nov 17 '15 at 11:36
  • I would add constructor in real life. But I have this class and a question is there any chance to avoid changes in it's logic for tests. Anyway, I guess I will stop on the answer, that it is not impossible to avoid changes in logic. thank you for your time and help – me1111 Nov 17 '15 at 12:00
  • If I would have constructor, I do the following instead of static block: private static TestController testController = new TestController(testService); But as I told , I am not allowed – me1111 Nov 17 '15 at 12:09
  • Sorry for confusion, I updated the post with class example. It is created by spring and depency injections is done by it too – me1111 Nov 17 '15 at 12:16