I've been trying to mock the service inside the controller on the producer side
@Autowired
private Service service;
@PostMapping(path = "/getone", consumes = "application/json", produces = "application/json")
public ResponseEntity<Response> getone(@RequestBody Test[] test) {
String appId = Utils.getId();
return new ResponseEntity<>(service.pub(test,id), HttpStatus.OK);
}
Here's how my base test class look like
@ExtendWith(SpringExtension.class)
@ActiveProfiles("test")
@SpringBootTest
@RunWith(PowerMockRunner.class)
public class ContractTest {
@Autowired
private WebApplicationContext context;
@Mock
private Service service;
@BeforeEach
void setup() {
mockStatic(Utils.class);
when(Utils.getId()).thenReturn("194");
Mockito.when(service.pub(Mockito.any(Test[].class),eq("194"))).thenReturn(TestUtils.publish_success_response());
StandaloneMockMvcBuilder standaloneMockMvcBuilder = MockMvcBuilders.standaloneSetup(publishApiController, this.publishService);
RestAssuredMockMvc.standaloneSetup(standaloneMockMvcBuilder);
}
There is an important difference between @Mock and @MockBean. For your test you need @MockBean
as you are replacing a Spring bean with a mock for your Spring Test Context.
Apart from this, you are mixing JUnit 4 (@RunWith
) and JUnit 5 (@ExtendWith
, @BeforeEach
).
If you just want to write a test for your controller using MockMvc
, you don't have to start the whole Spring Context with @SpringBootTest
. Spring Boot Test provides an annotation to only start a sliced context for your MVC components: @WebMvcTest
.
For the static mock of your Utils
class, you can use Mockito (since version 3.4.0) to reduce the number of additional dependencies and stick to what the Spring Boot Starter Test provides.
A possible test can look like the following:
// @ExtendWith(SpringExtension.class) not needed with recent Spring Boot versions
@ActiveProfiles("test")
@WebMvcTest
public class ContractTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private Service service;
@Test
void test() {
try(MockedStatic<Utils> mockedUtils = Mockito.mockStatic(Utils.class)) {
mockedUtils.when(Utils::getId).thenReturn("194");
when(service.pub(Mockito.any(Test[].class),eq("194"))).thenReturn(TestUtils.publish_success_response());
// ... your test
}
}
}