maloney
maloney

Reputation: 1653

Inject with MockMVC Test

I'm writing an Spring MVC integration test and want to mock an external service, which is embedded within the class structure. However, I can't seem to get the mock to work.

This is my class structure:

Controller:

@RestController
public class Controller {

    private final MyService service;

    @Autowired
    public Controller(MyService service) {
        this.service = service;
    }

    @RequestMapping(value = "/send", method = POST, produces = APPLICATION_JSON_VALUE)
    public void send(@RequestBody Response response) {
        service.sendNotification(response);
    }
}

Service:

@Service
public class MyService {

    // Client is external service to be mocked
    private final Client client;
    private final Factory factory;

    @Autowired
    public MyService(Client client, Factory factory) {
        this.factory = factory;
        this.client = client;
    }

    public void sendNotification(Response response) {
        // Implemented code some of which will be mocked
    }
}

Integration Test:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class IntegrationTest {

    MockMvc mockMvc;

    @Autowired
    MyService service;

    @Mock
    Client client;

    @Autowired
    Factory factory;

    @InjectMocks
    Controller controller;

    @Before
    public void setup() {
        initMocks(this);
        this.mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
    }

    @Test
    public void test1() {

        String json = "{/"Somejson/":/"test/"}";

        mockMvc.perform(post("/send")
            .contentType(MediaType.APPLICATION_JSON)
            .content(json))
            .andExpect(status().isCreated());
    }
}

This results in the service ending up as null. Can anyone spot what I am doing wrong? Thanks

Upvotes: 3

Views: 3019

Answers (1)

pvpkiran
pvpkiran

Reputation: 27068

Good thing is you are using constructor Injection in Controller and Service class. Which makes it easier to initialize with mocks

This should work.

public class IntegrationTest {

    MockMvc mockMvc;
    MyService service;
    Controller controller;

    @Mock
    Client client;

    @Autowired
    Factory factory;

    @Before
    public void setup() {
        initMocks(this);
        MyService service = new MyService(client, factory);
        controller = new Controller(service);
        this.mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
    }

Upvotes: 7

Related Questions