How to add multiple contracts for one method? Contract tests using Spring Cloud Contract Verifier + groovy

Viewed 91

I'm trying to make 2 cases for one method: when response contains a list of elements and an empty list. I have BaseTestClass for both cases, but response body generation should differ depending on the contract. Is it possible? If yes, how to do it? How do BaseTestClass knows which mock to call?

@ActiveProfiles("test")
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
@DirtiesContext
@AutoConfigureMessageVerifier
public class BaseTestClass {

    @Autowired
    private MyController myController;

    @MockBean
    private MyService myService;

    @BeforeEach
    public void SetUp() {
        StandaloneMockMvcBuilder standaloneMockMvcBuilder
                = MockMvcBuilders.standaloneSetup(channelController);
        standaloneMockMvcBuilder.setControllerAdvice(new MyExceptionHandler());
        standaloneMockMvcBuilder.setMessageConverters(new MappingJackson2HttpMessageConverter());
        RestAssuredMockMvc.standaloneSetup(standaloneMockMvcBuilder);
        //mockGetAllChannels(); // when it was the only contract, mock was called here
    }

    @Test
    void testChannelsOk() {
        mockGetAllChannels(createChannelList());
    }

    @Test
    void testEmptyList() {
        mockGetAllChannels(Collections.emptyList());
    }

    private void mockGetAllChannels(List<ChannelResponse.Channel> channelList) {
        doReturn(ChannelResponse.builder()
                .channels(channelList)
                .build())
                .when(myService)
                .getAllChannels();
    }

    private List<ChannelResponse.Channel> createChannelList() {
        //generation logic
}

Groovy file:

[
        Contract.make {
            name("two channels")
            request {
                method 'GET'
                url('/channels')
                headers {
                    header('Content-Type', 'application/json;charset=UTF-8')
                }
            }
            response {
                status 200
                body(
                        channels: [[
                                           id     : anyNonBlankString(),
                                           name   : anyNonBlankString(),
                                   ]
                        ]
                )
            }
        },

        Contract.make {
            name("empty list")
            request {
                method 'GET'
                url('/channels')
                headers {
                    header('Content-Type', 'application/json;charset=UTF-8')
                }
            }
            response {
                status 200
                body(
                        channels: []
                )
            }
        }
]

I also tried to make it in separate files, I'm not sure which approach is better. I saw this kind of example of doing multiple contracts:

@Test
    void testEmptyList()

but it doesn't work.

0 Answers
Related