Не удается смоделировать аннотированное поле с помощью Mockito - PullRequest
0 голосов
/ 25 марта 2020

Следующим является испытуемый объект RestClient. java

package com.demo.mockito;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.Validate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import com.demo.sample1.RestClient;
import com.demo.sample2.AboutApi;
import com.demo.sample3.ServiceInfo;
import com.demo.sample4.FeatureRepo;

@Component
@Slf4j
public class RestClient {

    @Value("${test.api.baseURL:http://localhost:80}")
    private String baseURL;

    private static String ACTIVE = "ACTIVE";

    @Autowired(required = false)
    private TokenService tokenService;

    private FeatureRepo featureRepo;

    RestClient(FeatureRepo featureRepo) {
        this.FeatureRepo = featureRepo;
    }

    public boolean isEnabled() {
        AboutApi aboutApi = new AboutApi(getApiClient());
        ServiceInfo serviceInfo = aboutApi.getMultiSiteServiceInfo();
        Validate.notNull(serviceInfo);
        return ACTIVE.equals(serviceInfo.getStatus());
    }

    private ApiClient getApiClient() {
        ApiClient apiClient = new ApiClient();
        apiClient.setBasePath(baseURL);
        return apiClient;
    }
}

А вот этот тест RestClientTest. java

package com.demo.mockito;

import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.powermock.modules.junit4.PowerMockRunner;
import com.demo.sample1.RestClient;
import com.demo.sample2.AboutApi;
import com.demo.sample3.ServiceInfo;
import com.demo.sample4.FeatureRepo;


@RunWith(PowerMockRunner.class)
public class RestClientTest {
    @InjectMocks private RestClient restClient;

    @Mock private AboutApi aboutApiClient;

    @Mock ServiceInfo serviceInfo;

    @Mock FeatureRepo featureRepo;

    @Before
    public void init() throws ApiException {
        when(aboutApiClient.getServiceInfo()).thenReturn(serviceInfo);
        when(serviceInfo.getStatus()).thenReturn("ACTIVE");
    }

    @Test
    public void testIsEnabled() throws ApiException {
        boolean status = restClient.isEnabled();
        assertTrue(status);
    }
}

Когда я запускаю тест, в идеале, когда он достигает 2-й строки метода RestClient. java isEnabled , вывод должен быть смоделирован, как указано в 1-й строке @ До , но он пытается вызвать реальный метод, приводящий к IllegalArgumentException .

Может кто-нибудь подскажите, пожалуйста, как мне правильно смоделировать этот вызов, не внося никаких изменений в файл RestClient. java?

1 Ответ

1 голос
/ 25 марта 2020

Редактировать: Обновлено

У меня проблема в строке AboutApi aboutApi = new AboutApi (getApiClient ()). Здесь он вызывает новый экземпляр, а не использует тот, который я высмеял. Я хочу знать, как я могу вставить свой смоделированный экземпляр AboutApi, не касаясь RestClient. java

В этом случае вы должны взглянуть на функциональность PowerMockito whenNew.

Вам нужно будет добавить аннотацию @PrepareForTest, чтобы она включала класс, который необходимо изменить, в вашем случае RestClient.

@RunWith(PowerMockRunner.class)
@PrepareForTest(RestClient.class)

Не уверен, является ли это опечатка в вашем вопросе, но метод, для которого нужно определить поведение, должен быть getMultiSiteServiceInfo вместо getServiceInfo.

@Test
public void testIsEnabled() throws Exception {

    Mockito.when(aboutApiClient.getMultiSiteServiceInfo()).thenReturn(serviceInfo);
    Mockito.when(serviceInfo.getStatus()).thenReturn("ACTIVE");

    PowerMockito.whenNew(AboutApi.class)
                .withAnyArguments()
                .thenReturn(aboutApiClient);

    boolean status = restClient.isEnabled();
    Assert.assertTrue(status);
}

Вы можете заменить withAnyArguments() на withArguments(Mockito.any(ApiClient.class)), если хотите быть более указать c.

Обратите внимание, что поля tokenService и baseUrl в вашем классе RestClient будут null.

...