Mocking service spring class autowired by constructor param using spock

时间:2018-02-26 17:40:56

标签: java spring-boot spock

I'm using spock to create my tests and now I have some problems because I need to mocking my service spring class that autowired a class from external API but that class is autowired by constructor with parameter on implementation.

I've searched on google but I didn't find any solution.

Below is my service class where I wanna to test methods.

@Service
@Slf4j
public class AddressService {

    @Autowired
    private VASApiClient vasApiClient;

    ConsResponse getAddress(String stateUpper, String postalCode, String number) {
        try {
            ConsRequest request = ConsRequest.builder()
                    .num(number)
                    .state(stateUpper)
                    .cepCode(postalCode)
                    .build();

            ConsResponse vasResponse = this.vasApiClient.consLogr(request);
            return vasResponse;

        } catch (VASApiClientException e) {
            log.error("Error calling ConsLogr IT CORE service.", e);
            throw ApiException.builder()
                    .code(ApiErrorMessage.UNKNOWN_ERROR)
                    .message("Error calling ConsultarLogradouro IT CORE service.")
                    .build();
        }
    }

}

Below is my Test Class:

    @ActiveProfiles("test")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
class AddressServiceTest extends Specification {

    @Autowired
    private AddressService addressService


    @Autowired
    private VASApiClient vasApiClient


    def 'find valid public place returned by exception'() {

        given:
        def state = 'XZ'
        def postalCode = '22280004'
        def streetNumber = '99'

        vasApiClient.consLogr(ConsRequest.builder()
                .num(streetNumber)
                .state(state)
                .cepCode(postalCode)
                .build()) >> { throw new VASApiClientException("Exception Test", "Err")}

        when:

        def actual = addressService.getAddress(state, postalCode, streetNumber)

        then:
        def ex = thrown(ApiException)
        ex.code == "unknown_error"


    }


    @TestConfiguration
    static class Configuration extends AbstractMongoConfiguration {

        private DetachedMockFactory factory = new DetachedMockFactory()


        @Bean
        AddressService addressService(){
            return factory.Mock(AddressService)
        }

        @Bean
        VASApiClient VASApiClient() {
            return factory.Mock(VASApiClient)
        }


    }
}

But when I attempting to run the test I get NullpointerException because inside the VasApiCliente the constructor receive a parameter as below:

    @Service
public class VASApiClient extends BaseAPIClient {

    @Autowired
    public VASApiClient(VasApiConfiguration configuration) {
        this.properties = configuration.getProperties();
    }
}

@EnableFeignClients
public abstract class BaseAPIClient {

    VASApiProperties properties;
    Map<String, Map<String, String>> propertiesMap = new HashMap();

    public BaseAPIClient() {
    }

    @PostConstruct
    private void initializePropertiesMap() {
        this.propertiesMap.put("consultLogr", this.properties.getConsultLogr());
        this.propertiesMap.put("consultSubscriber", this.properties.getConsultSubscriber));

    }
}

As mentioned previously when the BaseApi attempt to executed the properties field I get the NullPointerException.

I already attempt to return factory.Mock(VasApiCliente(Configurarion)) but not works because the Mock() method just accept .class and I've attempted return a real instance but it not works for me because I need to test using mock instances.

Kind regards

0 个答案:

没有答案