Bean не переопределяется при загрузке Spring - PullRequest
0 голосов
/ 09 апреля 2019

Я пытаюсь написать и протестировать приложение, которое использует Spring-Cloud с функциями Azure, следуя этому руководству. https://github.com/markusgulden/aws-tutorials/tree/master/spring-cloud-function/spring-cloud-function-azure/src/main/java/de/margul/awstutorials/springcloudfunction/azure

Я пытаюсь написать тестовый сценарий и переопределить компонент. Вот класс приложения, имеющий функцию Bean и функцию-обработчик.

@SpringBootApplication
@ComponentScan(basePackages = { "com.package" })

public class DataFunctions extends AzureSpringBootRequestHandler<GenericMessage<Optional<String>>, Data> {

@FunctionName("addData")
public HttpResponseMessage addDataRun(
        @HttpTrigger(name = "add", methods = {
                HttpMethod.POST }, authLevel = AuthorizationLevel.FUNCTION) HttpRequestMessage<Optional<String>> request,
        final ExecutionContext context) throws JsonParseException, JsonMappingException, IOException {
    context.getLogger().info("Java HTTP trigger processed a POST request.");

    try {
        handleRequest(new GenericMessage<Optional<String>>(request.getBody()), context);
    } catch (ServiceException ex) {
        ErrorMessage em = new ErrorMessage();
        return request.createResponseBuilder(handleException(ex, em)).body(em).build();
    }
    return request.createResponseBuilder(HttpStatus.CREATED).build();
}

@Autowired
MyService mService;

@Bean
public Consumer<GenericMessage<Optional<String>>> addData() {
    ObjectMapper mapper = new ObjectMapper();
    return req -> {
        SomeModel fp = null;
        try {
            fp = mapper.readValue(req.getPayload().get(), SomeModel.class);
        } catch (Exception e) {
            throw new ServiceException(e);
        }

        mService.addData(fp);
    };
}

}

Я хочу проверить, переопределив вышеуказанный компонент.

Конфигурация пружины Cosmosdb

@Configuration
@EnableDocumentDbRepositories
public class CosmosDBConfig extends AbstractDocumentDbConfiguration {

    @Value("${cosmosdb.collection.endpoint}")
    private String uri;

    @Value("${cosmosdb.collection.key}")
    private String key;

    @Value("${cosmosdb.collection.dbname}")
    private String dbName;

    @Value("${cosmosdb.connect.directly}")
    private Boolean connectDirectly;

    @Override
    public DocumentDBConfig getConfig() {
        ConnectionPolicy cp = ConnectionPolicy.GetDefault();
        if (connectDirectly) {
            cp.setConnectionMode(ConnectionMode.DirectHttps);
        } else {
            cp.setConnectionMode(ConnectionMode.Gateway);
        }
        return DocumentDBConfig.builder(uri, key, dbName).connectionPolicy(cp).build();
    }
}

Вот конфигурация

@TestConfiguration
@PropertySource(value = "classpath:application.properties", encoding = "UTF-8")
@Profile("test")
@Import({DataFunctions.class})
public class TestConfig {

    @Bean(name="addData")
    @Primary
    public Consumer<GenericMessage<Optional<String>>> addData() {
        return req -> {
            System.out.println("data mock");
        };
    }

    @Bean
    @Primary
    public DocumentDBConfig getConfig() {
        return Mockito.mock(DocumentDBConfig.class);
    }
}

Наконец тестовый класс

@RunWith(SpringRunner.class)
//@SpringBootTest //Enabling this gives initialization error.
@ActiveProfiles("test")
public class TempTest {

    @InjectMocks
    DataFunctions func;

    @Mock
    MyService mService;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
    }

    private Optional<String> createRequestString(final String res) throws IOException {
        InputStream iStream = TempTest.class.getResourceAsStream(res);
        String charset="UTF-8";
        try (BufferedReader br = new BufferedReader(new InputStreamReader(iStream, charset))) {
            return Optional.of(br.lines().collect(Collectors.joining(System.lineSeparator())));
        }
    }

    @Test
    public void testHttpPostTriggerJava() throws Exception {
        @SuppressWarnings("unchecked")
        final HttpRequestMessage<Optional<String>> req = mock(HttpRequestMessage.class);
        final Optional<String> queryBody = createRequestString("/test-data.json");
        doNothing().when(mService).addData(Mockito.any(SomeModel.class));
        doReturn(queryBody).when(req).getBody();

        doAnswer(new Answer<HttpResponseMessage.Builder>() {
            @Override
            public HttpResponseMessage.Builder answer(InvocationOnMock invocation) {
                HttpStatus status = (HttpStatus) invocation.getArguments()[0];
                return new HttpResponseMessageMock.HttpResponseMessageBuilderMock().status(status);
            }
        }).when(req).createResponseBuilder(any(HttpStatus.class));

        final ExecutionContext context = mock(ExecutionContext.class);
        doReturn(Logger.getGlobal()).when(context).getLogger();
        doReturn("addData").when(context).getFunctionName();

        // Invoke
        final HttpResponseMessage ret = func.addDataRun(req, context);

        // Verify
        assertEquals(ret.getStatus(), HttpStatus.CREATED);
    }
}

Для этого случая вместо тестовой конфигурации addData фактический компонент вызывается из класса DataFunctions. Также соединение с базой данных также создается, когда он должен использовать макет bean из моей тестовой конфигурации. Может кто-нибудь указать, что не так в моей тестовой конфигурации?

1 Ответ

0 голосов
/ 12 апреля 2019

Мне удалось разрешить первую часть загрузки конфигурации cosmos db, пометив ее

@Configuration
@EnableDocumentDbRepositories
@Profile("!test")
public class CosmosDBConfig extends AbstractDocumentDbConfiguration {
   ...
}

Также пришлось пометить bean-компонент хранилища как необязательный в службе.

public class MyService {
    @Autowired(required = false)
    private MyRepository myRepo;
}

Не использовалась никакая другая конфигурация загрузочной пружины, кроме этой.

@ActiveProfiles("test")
public class FunctionTest {
    ...
}

Для второй части предоставления имитирующей версии обработчиков Mock я просто сделал тестовый конфигурационный файл как приложение Spring, как показано ниже.

@SpringBootApplication
@ComponentScan(basePackages = { "com.boeing.da.helix.utm.traffic" })
@Profile("test")
public class TestConfiguration {

    public static void main(final String[] args) {
        SpringApplication.run(TestConfiguration.class, args);
    }
    @Bean(name="addData")
    @Primary
    public Consumer<GenericMessage<Optional<String>>> addData() {
        return req -> {
            System.out.println("data mock");
        };
    }   
}

и использовал этот конструктор из библиотеки функций Azure в весеннем облаке в моем конструкторе

public class AppFunctions
        extends AzureSpringBootRequestHandler<GenericMessage<Optional<String>>, List<Data>> {
    public AppFunctions(Class<?> configurationClass) {
        super(configurationClass);
    }
}

public AzureSpringBootRequestHandler(Class<?> configurationClass) {
    super(configurationClass);
}

Надеюсь, это кому-нибудь поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...