added test class
This commit is contained in:
psemenkov 2022-09-22 19:30:11 +03:00
parent 48036a9a91
commit da2f2c12db
7 changed files with 271 additions and 21 deletions

View file

@ -36,7 +36,7 @@ import static ru.spcex.clearing.account.utils.MatcherFactory.usingIgnoringFields
@ContextConfiguration(classes = {
HazelcastServiceTestConfiguration.class})
public class BankAccountServiceTest {
public static final Matcher<BankAccount> BANK_ACCOUNT_MATCHER = usingIgnoringFieldsComparator("id");
public static final Matcher<BankAccount> BANK_ACCOUNT_MATCHER = usingIgnoringFieldsComparator();
private static final int PARTITION = 0;
private static final String TOPIC_ACCOUNT_NEW = Consts.DESTINATION_BANK_ACCOUNT_NEW;
private static final String TOPIC_ACCOUNT_UPDATE = Consts.DESTINATION_BANK_ACCOUNT_UPDATE;

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>backend-api</artifactId>
@ -8,12 +8,12 @@
<description>Clearing backend API module</description>
<packaging>jar</packaging>
<parent>
<artifactId>clearing-parent</artifactId>
<parent>
<artifactId>clearing-parent</artifactId>
<groupId>ru.spcex.clearing</groupId>
<version>SPCEX-1.0.0.0</version>
</parent>
<properties>
<keycloak-spring-boot-starter.version>17.0.1</keycloak-spring-boot-starter.version>
@ -25,9 +25,9 @@
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>
@ -53,17 +53,38 @@
<groupId>ru.spcex.clearing</groupId>
<artifactId>classes</artifactId>
</dependency>
<!-- TEST -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.keycloak.bom</groupId>
<artifactId>keycloak-adapter-bom</artifactId>
<version>${keycloak-spring-boot-starter.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<groupId>org.keycloak.bom</groupId>
<artifactId>keycloak-adapter-bom</artifactId>
<version>${keycloak-spring-boot-starter.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

View file

@ -0,0 +1,72 @@
package ru.spcex.clearing.backendapi.controller.queue.account;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import ru.spcex.clearing.backendapi.controller.queue.config.Jackson2HttpConverterConfig;
import ru.spcex.clearing.backendapi.controller.queue.utils.JsonUtil;
import ru.spcex.clearing.backendapi.controller.queue.utils.MatcherFactory;
import ru.spcex.clearing.backendapi.controller.request.cud.account.BankAccountNewAction;
import ru.spcex.clearing.backendapi.controller.response.cud.CudResponse;
import javax.annotation.PostConstruct;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringJUnitWebConfig(classes = {
Jackson2HttpConverterConfig.class})
class BankAccountControllerTest {
public static final MatcherFactory.Matcher<CudResponse> CUD_RESPONSE_MATCHER = MatcherFactory.usingIgnoringFieldsComparator(CudResponse.class);
private static final String REST_URL = "/securities/bank-accounts/";
private static final CharacterEncodingFilter CHARACTER_ENCODING_FILTER = new CharacterEncodingFilter();
static {
CHARACTER_ENCODING_FILTER.setEncoding("UTF-8");
CHARACTER_ENCODING_FILTER.setForceEncoding(true);
}
@Autowired
public Environment env;
private MockMvc mockMvc;
@Autowired
private WebApplicationContext webApplicationContext;
@PostConstruct
private void postConstruct() {
mockMvc = MockMvcBuilders
.webAppContextSetup(webApplicationContext)
.addFilter(CHARACTER_ENCODING_FILTER)
// .apply(springSecurity())
.build();
}
@Test
void add() throws Exception {
BankAccountNewAction bankAccountNewAction = new BankAccountNewAction();
ResultActions action = mockMvc.perform(MockMvcRequestBuilders.post(REST_URL)
.contentType(MediaType.APPLICATION_JSON)
// .with(userHttpBasic(admin))
.content(JsonUtil.writeValue(bankAccountNewAction)))
.andExpect(status().isCreated());
CudResponse created = CUD_RESPONSE_MATCHER.readFromJson(action);
}
@Test
void update() {
}
@Test
void delete() {
}
}

View file

@ -0,0 +1,39 @@
package ru.spcex.clearing.backendapi.controller.queue.config;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
@Configuration
public class Jackson2HttpConverterConfig {
@Bean("customJsonHttpConverter")
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
return new MappingJackson2HttpMessageConverter(JacksonObjectMapper.getMapper());
}
public static class JacksonObjectMapper extends ObjectMapper {
private static final ObjectMapper MAPPER = new JacksonObjectMapper();
private JacksonObjectMapper() {
//настройки Ильи
configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);
//настройки какие были на курсе пока не нужны..
// модуль для корректной сериализации LocalDateTime в поля JSON - JavaTimeModule модуль библиотеки jackson-datatype-jsr310
// registerModule(new JavaTimeModule());
// configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
// запрещаем доступ ко всем полям и методам класса и потом разрешаем доступ только к полям, нужны чтобы не было лишних полей из-за методов как: public boolean isExcess()
// setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
// setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
// не сериализуем null-поля
// setSerializationInclusion(JsonInclude.Include.NON_NULL);
}
public static ObjectMapper getMapper() {
return MAPPER;
}
}
}

View file

@ -0,0 +1,38 @@
package ru.spcex.clearing.backendapi.controller.queue.utils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectReader;
import java.io.IOException;
import java.util.List;
import static ru.spcex.clearing.backendapi.controller.queue.config.Jackson2HttpConverterConfig.JacksonObjectMapper.getMapper;
public class JsonUtil {
public static <T> List<T> readValues(String json, Class<T> clazz) {
ObjectReader reader = getMapper().readerFor(clazz);
try {
return reader.<T>readValues(json).readAll();
} catch (IOException e) {
throw new IllegalArgumentException("Invalid read array from JSON:\n'" + json + "'", e);
}
}
public static <T> T readValue(String json, Class<T> clazz) {
try {
return getMapper().readValue(json, clazz);
} catch (IOException e) {
throw new IllegalArgumentException("Invalid read from JSON:\n'" + json + "'", e);
}
}
public static <T> String writeValue(T obj) {
try {
return getMapper().writeValueAsString(obj);
} catch (JsonProcessingException e) {
throw new IllegalStateException("Invalid write to JSON:\n'" + obj + "'", e);
}
}
}

View file

@ -0,0 +1,82 @@
package ru.spcex.clearing.backendapi.controller.queue.utils;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.ResultMatcher;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.function.BiConsumer;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Factory for creating test matchers.
* <p>
* Comparing actual and expected objects via AssertJ
* Support converting json MvcResult to objects for comparation.
*/
public class MatcherFactory {
public static <T> Matcher<T> usingAssertions(Class<T> clazz, BiConsumer<T, T> assertion, BiConsumer<Iterable<T>, Iterable<T>> iterableAssertion) {
return new Matcher<>(clazz, assertion, iterableAssertion);
}
public static <T> Matcher<T> usingEqualsComparator(Class<T> clazz) {
return usingAssertions(clazz,
(a, e) -> assertThat(a).isEqualTo(e),
(a, e) -> assertThat(a).isEqualTo(e));
}
public static <T> Matcher<T> usingIgnoringFieldsComparator(Class<T> clazz, String... fieldsToIgnore) {
return usingAssertions(clazz,
(a, e) -> assertThat(a).usingRecursiveComparison().ignoringFields(fieldsToIgnore).isEqualTo(e),
(a, e) -> assertThat(a).usingRecursiveFieldByFieldElementComparatorIgnoringFields(fieldsToIgnore).isEqualTo(e));
}
public static class Matcher<T> {
private final Class<T> clazz;
private final BiConsumer<T, T> assertion;
private final BiConsumer<Iterable<T>, Iterable<T>> iterableAssertion;
private Matcher(Class<T> clazz, BiConsumer<T, T> assertion, BiConsumer<Iterable<T>, Iterable<T>> iterableAssertion) {
this.clazz = clazz;
this.assertion = assertion;
this.iterableAssertion = iterableAssertion;
}
private static String getContent(MvcResult result) throws UnsupportedEncodingException {
return result.getResponse().getContentAsString();
}
public void assertMatch(T actual, T expected) {
assertion.accept(actual, expected);
}
@SafeVarargs
public final void assertMatch(Iterable<T> actual, T... expected) {
assertMatch(actual, List.of(expected));
}
public void assertMatch(Iterable<T> actual, Iterable<T> expected) {
iterableAssertion.accept(actual, expected);
}
public ResultMatcher contentJson(T expected) {
return result -> assertMatch(JsonUtil.readValue(getContent(result), clazz), expected);
}
@SafeVarargs
public final ResultMatcher contentJson(T... expected) {
return contentJson(List.of(expected));
}
public ResultMatcher contentJson(Iterable<T> expected) {
return result -> assertMatch(JsonUtil.readValues(getContent(result), clazz), expected);
}
public T readFromJson(ResultActions action) throws UnsupportedEncodingException {
return JsonUtil.readValue(getContent(action.andReturn()), clazz);
}
}
}

View file

@ -15,13 +15,11 @@ import java.time.Instant;
public abstract class AbstractUpdateMapService implements InitializingBean,
EntryAddedListener<Long, Object>, EntryUpdatedListener<Long, Object>, EntryRemovedListener<Long, Object> {
private final Logger log = LoggerFactory.getLogger(this.getClass());
protected final String EVENT_CREATE="CREATE";
protected final String EVENT_UPDATE="UPDATE";
protected final String EVENT_DELETE="DELETE";
protected final String EVENT_CREATE = "CREATE";
protected final String EVENT_UPDATE = "UPDATE";
protected final String EVENT_DELETE = "DELETE";
protected final HazelcastInstance hazelcastServerInstance;
private final Logger log = LoggerFactory.getLogger(this.getClass());
public AbstractUpdateMapService(HazelcastInstance hazelcastServerInstance) {
this.hazelcastServerInstance = hazelcastServerInstance;