From 00ce9c8a40a13d8418d851307603975ed9ed1920 Mon Sep 17 00:00:00 2001 From: Anton Romanov Date: Tue, 7 Jun 2022 16:39:22 +0400 Subject: [PATCH] add tests --- build.gradle | 6 +- src/main/java/ru/ulstu/UserService.java | 45 ++++++++++++++ src/main/java/ru/ulstu/entity/BaseEntity.java | 36 ++++++++++++ src/main/java/ru/ulstu/entity/User.java | 43 ++++++++++++++ .../exception/UserNotValidException.java | 18 ++++++ .../java/ru/ulstu/persistence/DbStore.java | 27 +++++++++ .../java/ru/ulstu/persistence/FileStore.java | 58 +++++++++++++++++++ .../ru/ulstu/persistence/PersistentStore.java | 24 ++++++++ .../java/ru/ulstu/util/PropertyManager.java | 57 ++++++++++++++++++ src/test/java/ru/ulstu/DbStoreTest.java | 33 +++++++++++ src/test/java/ru/ulstu/FileStoreTest.java | 33 +++++++++++ src/test/java/ru/ulstu/UserServiceTest.java | 26 +++++++++ src/test/resources/config.properties | 8 +++ 13 files changed, 412 insertions(+), 2 deletions(-) create mode 100644 src/main/java/ru/ulstu/UserService.java create mode 100644 src/main/java/ru/ulstu/entity/BaseEntity.java create mode 100644 src/main/java/ru/ulstu/entity/User.java create mode 100644 src/main/java/ru/ulstu/exception/UserNotValidException.java create mode 100644 src/main/java/ru/ulstu/persistence/DbStore.java create mode 100644 src/main/java/ru/ulstu/persistence/FileStore.java create mode 100644 src/main/java/ru/ulstu/persistence/PersistentStore.java create mode 100644 src/main/java/ru/ulstu/util/PropertyManager.java create mode 100644 src/test/java/ru/ulstu/DbStoreTest.java create mode 100644 src/test/java/ru/ulstu/FileStoreTest.java create mode 100644 src/test/java/ru/ulstu/UserServiceTest.java create mode 100644 src/test/resources/config.properties diff --git a/build.gradle b/build.gradle index b081818..cf6eaa4 100644 --- a/build.gradle +++ b/build.gradle @@ -33,8 +33,10 @@ dependencies { implementation group: 'org.slf4j', name: 'slf4j-api', version: versionSLF4J implementation group: 'nz.net.ultraq.thymeleaf', name: 'thymeleaf-layout-dialect', version: '3.1.0' - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' + testImplementation group: 'org.powermock', name: 'powermock-module-junit4', version: '1.7.4' + testImplementation group: 'org.powermock', name: 'powermock-api-mockito', version: '1.7.4' + testImplementation group: 'org.powermock', name: 'powermock-api-mockito-common', version: '1.7.4' + testImplementation group: 'org.mockito', name: 'mockito-all', version: '1.10.19' testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-test' } diff --git a/src/main/java/ru/ulstu/UserService.java b/src/main/java/ru/ulstu/UserService.java new file mode 100644 index 0000000..8beb72d --- /dev/null +++ b/src/main/java/ru/ulstu/UserService.java @@ -0,0 +1,45 @@ +package ru.ulstu; + +import ru.ulstu.entity.User; +import ru.ulstu.exception.UserNotValidException; +import ru.ulstu.persistence.DbStore; +import ru.ulstu.persistence.FileStore; +import ru.ulstu.persistence.PersistentStore; +import ru.ulstu.util.PropertyManager; + +import java.io.IOException; +import java.util.List; +import java.util.stream.Collectors; + +public class UserService { + private PersistentStore persistentStore; + PropertyManager propertyManager = PropertyManager.getInstance(); + + public UserService(PersistentStore persistentStore) { + this.persistentStore = persistentStore; + } + + public UserService() { + persistentStore = propertyManager.getTargetStorage().equals("file") + ? new FileStore(User.class) + : new DbStore(User.class); + } + + public User saveUser(User user) throws UserNotValidException, IOException { + validateUser(user); + return persistentStore.save(user); + } + + public List getUsers() throws IOException { + return persistentStore.readAll() + .stream() + .limit(10) + .collect(Collectors.toList()); + } + + private void validateUser(User user) throws UserNotValidException { + if (user.getLogin() == null || user.getLogin().equals("")) { + throw new UserNotValidException("Пустой логин", UserNotValidException.Code.EMPTY_LOGIN); + } + } +} \ No newline at end of file diff --git a/src/main/java/ru/ulstu/entity/BaseEntity.java b/src/main/java/ru/ulstu/entity/BaseEntity.java new file mode 100644 index 0000000..7c770d3 --- /dev/null +++ b/src/main/java/ru/ulstu/entity/BaseEntity.java @@ -0,0 +1,36 @@ +package ru.ulstu.entity; + +import java.util.Objects; + +public abstract class BaseEntity { + protected Long id; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + @Override + public int hashCode() { + return Objects.hashCode(this.id); + } + + @Override + public boolean equals(Object o) { + // self check + if (this == o) + return true; + // null check + if (o == null) + return false; + // type check and cast + if (getClass() != o.getClass()) + return false; + BaseEntity baseEntity = (BaseEntity) o; + // field comparison + return Objects.equals(id, (baseEntity.getId())); + } +} diff --git a/src/main/java/ru/ulstu/entity/User.java b/src/main/java/ru/ulstu/entity/User.java new file mode 100644 index 0000000..bbe6966 --- /dev/null +++ b/src/main/java/ru/ulstu/entity/User.java @@ -0,0 +1,43 @@ +package ru.ulstu.entity; + +public class User extends BaseEntity { + private String login; + private String password; + private String fullName; + + public User() { + } + + public User(Long id, String login) { + this.login = login; + this.id = id; + } + + public User(String login) { + this.login = login; + } + + public String getLogin() { + return login; + } + + public void setLogin(String login) { + this.login = login; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getFullName() { + return fullName; + } + + public void setFullName(String fullName) { + this.fullName = fullName; + } +} diff --git a/src/main/java/ru/ulstu/exception/UserNotValidException.java b/src/main/java/ru/ulstu/exception/UserNotValidException.java new file mode 100644 index 0000000..94c0ff2 --- /dev/null +++ b/src/main/java/ru/ulstu/exception/UserNotValidException.java @@ -0,0 +1,18 @@ +package ru.ulstu.exception; + +public class UserNotValidException extends Exception { + public enum Code { + EMPTY_LOGIN + } + + private final Code code; + + public UserNotValidException(String message, Code code) { + super(message); + this.code = code; + } + + public Code getCode() { + return code; + } +} diff --git a/src/main/java/ru/ulstu/persistence/DbStore.java b/src/main/java/ru/ulstu/persistence/DbStore.java new file mode 100644 index 0000000..f9d62ea --- /dev/null +++ b/src/main/java/ru/ulstu/persistence/DbStore.java @@ -0,0 +1,27 @@ +package ru.ulstu.persistence; + +import ru.ulstu.entity.BaseEntity; + +import java.util.List; + +public class DbStore extends PersistentStore { + + public DbStore(Class type) { + super(type); + } + + @Override + public List save(List entities) { + throw new RuntimeException("not implemented yet"); + } + + @Override + public T save(T entity) { + throw new RuntimeException("not implemented yet"); + } + + @Override + public List readAll() { + throw new RuntimeException("not implemented yet"); + } +} diff --git a/src/main/java/ru/ulstu/persistence/FileStore.java b/src/main/java/ru/ulstu/persistence/FileStore.java new file mode 100644 index 0000000..08ea4b1 --- /dev/null +++ b/src/main/java/ru/ulstu/persistence/FileStore.java @@ -0,0 +1,58 @@ +package ru.ulstu.persistence; + +import com.fasterxml.jackson.databind.ObjectMapper; +import ru.ulstu.entity.BaseEntity; +import ru.ulstu.util.PropertyManager; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +public class FileStore extends PersistentStore { + private ObjectMapper mapper; + private File storageFile; + + public FileStore(Class type) { + super(type); + this.mapper = new ObjectMapper(); + this.storageFile = new File(PropertyManager.getInstance().getFileStorage()); + } + + @Override + public List save(List entities) throws IOException { + mapper.writeValue(storageFile, entities); + return entities; + } + + @Override + public T save(T entity) throws IOException { + List entities = readAll(); + entities.remove(entity); + entity.setId(getGeneratedId(entities)); + entities.add(entity); + save(entities); + return entity; + } + + private Long getGeneratedId(List entities) { + if (entities == null || entities.isEmpty()) { + return 1L; + } + entities.sort(Comparator.comparing(BaseEntity::getId)); + Long lastId = entities.get(entities.size() - 1).getId(); + return lastId == null ? 1 : lastId + 1; + } + + @Override + public List readAll() throws IOException { + return mapper.readValue(storageFile, mapper.getTypeFactory().constructCollectionType(List.class, getType())); + } + + + public void reset() throws IOException { + List list = new ArrayList(); + save(list); + } +} diff --git a/src/main/java/ru/ulstu/persistence/PersistentStore.java b/src/main/java/ru/ulstu/persistence/PersistentStore.java new file mode 100644 index 0000000..8d6f22a --- /dev/null +++ b/src/main/java/ru/ulstu/persistence/PersistentStore.java @@ -0,0 +1,24 @@ +package ru.ulstu.persistence; + +import ru.ulstu.entity.BaseEntity; + +import java.io.IOException; +import java.util.List; + +public abstract class PersistentStore { + private Class type; + + protected PersistentStore(Class type) { + this.type = type; + } + + public abstract List save(List entities) throws IOException; + + public abstract T save(T entity) throws IOException; + + public abstract List readAll() throws IOException; + + public Class getType() { + return type; + } +} diff --git a/src/main/java/ru/ulstu/util/PropertyManager.java b/src/main/java/ru/ulstu/util/PropertyManager.java new file mode 100644 index 0000000..6dc2eba --- /dev/null +++ b/src/main/java/ru/ulstu/util/PropertyManager.java @@ -0,0 +1,57 @@ +package ru.ulstu.util; + +import java.io.InputStream; +import java.util.Properties; + +public class PropertyManager { + public static final PropertyManager INSTANCE = new PropertyManager(); + private final static String CONFIG_NAME = "config.properties"; + + private enum ConfigKey { + FILE_STORAGE("fileStorage"), + TARGET_STORAGE("targetStorage"), + DB_NAME("dbName"), + DB_USER("dbUser"), + DB_PASSWORD("dbPassword"), + DB_HOST("dbHost"), + DB_PORT("dbPort"); + + private String keyName; + + ConfigKey(String key) { + this.keyName = key; + } + + public String getKeyName() { + return keyName; + } + } + + private Properties properties; + + private PropertyManager() { + properties = new Properties(); + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + try (InputStream resourceStream = loader.getResourceAsStream(CONFIG_NAME)) { + properties.load(resourceStream); + } catch (Exception ex) { + System.out.println(String.format("Config read error: %s", ex.getMessage())); + } + } + + public static PropertyManager getInstance() { + return INSTANCE; + } + + public String getFileStorage() { + return properties.getProperty(ConfigKey.FILE_STORAGE.getKeyName()); + } + + public String getTargetStorage() { + return properties.getProperty(ConfigKey.TARGET_STORAGE.getKeyName()); + } + + public void getProperty(String key) { + properties.getProperty(key); + } +} diff --git a/src/test/java/ru/ulstu/DbStoreTest.java b/src/test/java/ru/ulstu/DbStoreTest.java new file mode 100644 index 0000000..286e204 --- /dev/null +++ b/src/test/java/ru/ulstu/DbStoreTest.java @@ -0,0 +1,33 @@ +package ru.ulstu; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; +import ru.ulstu.entity.User; +import ru.ulstu.persistence.DbStore; + +import java.io.IOException; + +import static org.powermock.api.mockito.PowerMockito.when; + +public class DbStoreTest { + + @Mock + private DbStore dbStore = PowerMockito.mock(DbStore.class); + + @Before + public void before() { + Mockito.reset(dbStore); + } + + @Test + public void saveNewUserToFileTest() throws IOException { + User newUser = new User("login"); + when(dbStore.save(Mockito.any(User.class))).thenReturn(new User(1L, "login")); + newUser = (User) dbStore.save(newUser); + Assert.assertEquals((long) newUser.getId(), 1L); + } +} diff --git a/src/test/java/ru/ulstu/FileStoreTest.java b/src/test/java/ru/ulstu/FileStoreTest.java new file mode 100644 index 0000000..316d89e --- /dev/null +++ b/src/test/java/ru/ulstu/FileStoreTest.java @@ -0,0 +1,33 @@ +package ru.ulstu; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import ru.ulstu.entity.User; +import ru.ulstu.persistence.FileStore; +import ru.ulstu.persistence.PersistentStore; + +import java.io.IOException; + +public class FileStoreTest { + + private final PersistentStore fileStore = new FileStore<>(User.class); + + @Before + public void before() throws IOException { + ((FileStore) fileStore).reset(); + } + + @Test + public void saveNewUserToFileTest() throws IOException { + User newUser = new User(""); + newUser = fileStore.save(newUser); + Assert.assertEquals((long) newUser.getId(), 1L); + } + + @After + public void after() throws IOException { + ((FileStore) fileStore).reset(); + } +} diff --git a/src/test/java/ru/ulstu/UserServiceTest.java b/src/test/java/ru/ulstu/UserServiceTest.java new file mode 100644 index 0000000..7356d3e --- /dev/null +++ b/src/test/java/ru/ulstu/UserServiceTest.java @@ -0,0 +1,26 @@ +package ru.ulstu; + +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; +import ru.ulstu.entity.User; +import ru.ulstu.exception.UserNotValidException; +import ru.ulstu.persistence.FileStore; + +import java.io.IOException; + +public class UserServiceTest { + + @Mock + private FileStore fileStore = PowerMockito.mock(FileStore.class); + + private final UserService userService = new UserService(fileStore); + + @Test + public void testUserSave() throws UserNotValidException, IOException { + User user = new User("login"); + userService.saveUser(user); + Mockito.verify(fileStore, Mockito.times(1)).save(user); + } +} diff --git a/src/test/resources/config.properties b/src/test/resources/config.properties new file mode 100644 index 0000000..56c009f --- /dev/null +++ b/src/test/resources/config.properties @@ -0,0 +1,8 @@ +# Possible values: file or db +targetStorage=file +fileStorage=test-users.json +dbHost=localhost +dbName=unit-test +dbPort=5432 +dbUser=postgres +dbPassword=postgres \ No newline at end of file