Skip to content

Commit

Permalink
DC-1055: More Junit 5 migrations (#1677)
Browse files Browse the repository at this point in the history
Migrate more unit tests to JUnit 5

- migrate all unit tests except for embedded database tests
- where possible, tests were changed to not use a spring context
- spring context tests were changed to use `@ContextConfiguration` to limit the number of autowired components
  • Loading branch information
pshapiro4broad authored May 7, 2024
1 parent d631a36 commit b9ff77b
Show file tree
Hide file tree
Showing 25 changed files with 1,107 additions and 920 deletions.
31 changes: 31 additions & 0 deletions src/test/java/bio/terra/common/TestUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@
import com.google.cloud.storage.Acl;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.time.Duration;
import java.time.LocalDateTime;
Expand All @@ -52,6 +55,7 @@
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpHead;
Expand Down Expand Up @@ -355,4 +359,31 @@ public static <T> T extractValueFromPrivateObject(Object object, String fieldNam
return objectMapper.convertValue(
ReflectionTestUtils.getField(object, fieldName), new TypeReference<>() {});
}

public static String loadJson(final String resourcePath) {
try (InputStream stream = TestUtils.class.getClassLoader().getResourceAsStream(resourcePath)) {
if (stream == null) {
throw new FileNotFoundException(resourcePath);
}
return IOUtils.toString(stream, StandardCharsets.UTF_8);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

public static <T> T loadObject(final String resourcePath, final Class<T> resourceClass) {
try {
return objectMapper.readerFor(resourceClass).readValue(loadJson(resourcePath));
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}

public static <T> T loadObject(final String resourcePath, final TypeReference<T> typeReference) {
try {
return objectMapper.readerFor(typeReference).readValue(loadJson(resourcePath));
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}
28 changes: 28 additions & 0 deletions src/test/java/bio/terra/common/fixtures/UnitTestConfiguration.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package bio.terra.common.fixtures;

import bio.terra.app.configuration.ApplicationConfiguration;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

@Profile("unittest")
@Configuration
public class UnitTestConfiguration {

private final ObjectMapper objectMapper = new ApplicationConfiguration().objectMapper();

@Bean("tdrServiceAccountEmail")
public String tdrServiceAccountEmail() {
// Provide a default value for the service account email when running a spring-context aware
// unit test to avoid having to set it in the test environment.
return "";
}

@Bean("objectMapper")
public ObjectMapper objectMapper() {
// Provide the same objectmapper that the application configuration provides. Without this,
// the default Jackson objectmapper is used, which is configured differently.
return objectMapper;
}
}
27 changes: 10 additions & 17 deletions src/test/java/bio/terra/service/common/AssetUtils.java
Original file line number Diff line number Diff line change
@@ -1,28 +1,19 @@
package bio.terra.service.common;

import bio.terra.common.Relationship;
import bio.terra.common.fixtures.JsonLoader;
import bio.terra.common.TestUtils;
import bio.terra.service.dataset.AssetColumn;
import bio.terra.service.dataset.AssetRelationship;
import bio.terra.service.dataset.AssetSpecification;
import bio.terra.service.dataset.AssetTable;
import bio.terra.service.dataset.DatasetTable;
import bio.terra.service.tabulardata.WalkRelationship;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.springframework.stereotype.Component;

@Component
public class AssetUtils {
private final JsonLoader jsonLoader;

public AssetUtils(JsonLoader jsonLoader) {
this.jsonLoader = jsonLoader;
}

public AssetSpecification buildTestAssetSpec() throws IOException {
public static AssetSpecification buildTestAssetSpec() {
AssetTable assetTable_sample = setUpAssetTable("ingest-test-dataset-table-sample.json");
AssetTable assetTable_participant =
setUpAssetTable("ingest-test-dataset-table-participant.json");
Expand All @@ -41,7 +32,8 @@ public AssetSpecification buildTestAssetSpec() throws IOException {
.orElseThrow());
}

public WalkRelationship buildExampleWalkRelationship(AssetSpecification assetSpecification) {
public static WalkRelationship buildExampleWalkRelationship(
AssetSpecification assetSpecification) {
DatasetTable participantTable =
assetSpecification.getAssetTableByName("participant").getTable();
DatasetTable sampleTable = assetSpecification.getAssetTableByName("sample").getTable();
Expand All @@ -59,12 +51,13 @@ public WalkRelationship buildExampleWalkRelationship(AssetSpecification assetSpe
return WalkRelationship.ofAssetRelationship(sampleParticipantRelationship);
}

private AssetTable setUpAssetTable(String resourcePath) throws IOException {
DatasetTable datasetTable = jsonLoader.loadObject(resourcePath, DatasetTable.class);
private static AssetTable setUpAssetTable(String resourcePath) {
DatasetTable datasetTable = TestUtils.loadObject(resourcePath, DatasetTable.class);
datasetTable.id(UUID.randomUUID());
List<AssetColumn> columns = new ArrayList<>();
datasetTable.getColumns().stream()
.forEach(c -> columns.add(new AssetColumn().datasetColumn(c).datasetTable(datasetTable)));
List<AssetColumn> columns =
datasetTable.getColumns().stream()
.map(c -> new AssetColumn().datasetColumn(c).datasetTable(datasetTable))
.toList();
return new AssetTable().datasetTable(datasetTable).columns(columns);
}
}
115 changes: 64 additions & 51 deletions src/test/java/bio/terra/service/configuration/ConfigServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.lessThan;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.Mockito.mock;

import bio.terra.app.configuration.ApplicationConfiguration;
import bio.terra.app.configuration.SamConfiguration;
import bio.terra.app.controller.exception.ValidationException;
import bio.terra.common.category.Unit;
Expand All @@ -24,30 +27,35 @@
import bio.terra.model.ConfigParameterModel;
import bio.terra.service.configuration.exception.ConfigNotFoundException;
import bio.terra.service.configuration.exception.DuplicateConfigNameException;
import bio.terra.service.resourcemanagement.google.GoogleResourceConfiguration;
import java.util.List;
import org.apache.commons.codec.binary.StringUtils;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest(properties = {"datarepo.testWithEmbeddedDatabase=false"})
@AutoConfigureMockMvc
@ActiveProfiles({"google", "unittest"})
@Category(Unit.class)
public class ConfigServiceTest {

@Autowired private ConfigurationService configService;

@Autowired private SamConfiguration samConfiguration;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
@Tag(Unit.TAG)
class ConfigServiceTest {

private SamConfiguration samConfiguration;

private ConfigurationService configService;

@BeforeEach
void beforeEach() {
samConfiguration = new SamConfiguration("", "", 5, 10, 15);
configService =
new ConfigurationService(
samConfiguration,
mock(GoogleResourceConfiguration.class),
mock(ApplicationConfiguration.class));
}

@Test
public void configBasicTest() throws Exception {
void configBasicTest() {
// Order of tests can cause config state to change, so ensure config is reset otherwise tests
// may fail
configService.reset();
Expand Down Expand Up @@ -87,13 +95,13 @@ public void configBasicTest() throws Exception {
configService.setConfig(groupModel);

// Retrieve specific config
Integer expectedValue = retryInitialWaitSeconds + delta;
int expectedValue = retryInitialWaitSeconds + delta;
ConfigModel configModel = configService.getConfig(SAM_RETRY_INITIAL_WAIT_SECONDS.name());
assertThat(configModel.getConfigType(), equalTo(ConfigModel.ConfigTypeEnum.PARAMETER));
assertThat(
"Int param matches",
configModel.getParameter().getValue(),
equalTo(expectedValue.toString()));
equalTo(String.valueOf(expectedValue)));

// Reset config and check result
configService.reset();
Expand All @@ -107,18 +115,20 @@ public void configBasicTest() throws Exception {
configModelList, SAM_OPERATION_TIMEOUT_SECONDS.name(), operationTimeoutSeconds);
}

@Test(expected = DuplicateConfigNameException.class)
public void testDuplicateConfigException() throws Exception {
configService.addParameter(SAM_RETRY_INITIAL_WAIT_SECONDS, 42);
@Test
void testDuplicateConfigException() {
assertThrows(
DuplicateConfigNameException.class,
() -> configService.addParameter(SAM_RETRY_INITIAL_WAIT_SECONDS, 42));
}

@Test(expected = ConfigNotFoundException.class)
public void testConfigNotFoundLookup() throws Exception {
configService.getConfig("xyzzy");
@Test
void testConfigNotFoundLookup() {
assertThrows(ConfigNotFoundException.class, () -> configService.getConfig("xyzzy"));
}

@Test(expected = ConfigNotFoundException.class)
public void testConfigNotFoundSet() throws Exception {
@Test
void testConfigNotFoundSet() {
ConfigGroupModel groupModel =
new ConfigGroupModel()
.label("configNotFoundSetTest")
Expand All @@ -127,38 +137,38 @@ public void testConfigNotFoundSet() throws Exception {
.name("xyzzy")
.configType(ConfigModel.ConfigTypeEnum.PARAMETER)
.parameter(new ConfigParameterModel().value(String.valueOf(22))));
configService.setConfig(groupModel);
assertThrows(ConfigNotFoundException.class, () -> configService.setConfig(groupModel));
}

private void checkIntParamValue(
List<ConfigModel> configModelList, String name, Integer expectedValue) {
List<ConfigModel> configModelList, String name, int expectedValue) {
for (ConfigModel configModel : configModelList) {
if (StringUtils.equals(configModel.getName(), name)) {
assertThat(configModel.getConfigType(), equalTo(ConfigModel.ConfigTypeEnum.PARAMETER));
assertThat(
"Int param matches",
configModel.getParameter().getValue(),
equalTo(expectedValue.toString()));
equalTo(String.valueOf(expectedValue)));
return;
}
}
fail("Failed to find config param " + name);
}

@Test
public void testFaultSimple() throws Exception {
void testFaultSimple() {
configService.addFaultSimple(UNIT_TEST_SIMPLE_FAULT);

boolean simpleTest = configService.testInsertFault(UNIT_TEST_SIMPLE_FAULT);
assertFalse("Simple fault is disabled", simpleTest);
assertFalse(simpleTest, "Simple fault is disabled");

configService.setFault(UNIT_TEST_SIMPLE_FAULT.name(), true);
simpleTest = configService.testInsertFault(UNIT_TEST_SIMPLE_FAULT);
assertTrue("Simple fault is enabled", simpleTest);
assertTrue(simpleTest, "Simple fault is enabled");
}

@Test
public void testCountedFixed() throws Exception {
void testCountedFixed() {
setFaultCounted(5, 3, 20, ConfigFaultCountedModel.RateStyleEnum.FIXED);
configService.setFault(UNIT_TEST_COUNTED_FAULT.name(), true);

Expand Down Expand Up @@ -197,7 +207,7 @@ public void testCountedFixed() throws Exception {
}

@Test
public void testCountedRandom() throws Exception {
void testCountedRandom() {
setFaultCounted(0, -1, 10, ConfigFaultCountedModel.RateStyleEnum.RANDOM);
configService.setFault(UNIT_TEST_COUNTED_FAULT.name(), true);

Expand All @@ -213,16 +223,19 @@ public void testCountedRandom() throws Exception {
assertThat(inserted, allOf(greaterThan(900), lessThan(1100)));
}

@Test(expected = DuplicateConfigNameException.class)
public void testDuplicateFaultConfigException() throws Exception {
configService.addFaultCounted(
UNIT_TEST_COUNTED_FAULT, 0, -1, 10, ConfigFaultCountedModel.RateStyleEnum.RANDOM);
@Test
void testDuplicateFaultConfigException() {
configService.addFaultCounted(
UNIT_TEST_COUNTED_FAULT, 0, -1, 10, ConfigFaultCountedModel.RateStyleEnum.RANDOM);
assertThrows(
DuplicateConfigNameException.class,
() ->
configService.addFaultCounted(
UNIT_TEST_COUNTED_FAULT, 0, -1, 10, ConfigFaultCountedModel.RateStyleEnum.RANDOM));
}

@Test(expected = ValidationException.class)
public void testMismatchedFaultTypeSet() throws Exception {
@Test
void testMismatchedFaultTypeSet() {
setFaultCounted(0, -1, 10, ConfigFaultCountedModel.RateStyleEnum.RANDOM);
ConfigFaultModel faultModel =
new ConfigFaultModel()
Expand All @@ -237,11 +250,11 @@ public void testMismatchedFaultTypeSet() throws Exception {
.name(UNIT_TEST_COUNTED_FAULT.name())
.configType(ConfigModel.ConfigTypeEnum.FAULT)
.fault(faultModel));
configService.setConfig(groupModel);
assertThrows(ValidationException.class, () -> configService.setConfig(groupModel));
}

@Test(expected = ValidationException.class)
public void testMissingCountedModelSet() throws Exception {
@Test
void testMissingCountedModelSet() {
setFaultCounted(0, -1, 10, ConfigFaultCountedModel.RateStyleEnum.RANDOM);
ConfigFaultModel faultModel =
new ConfigFaultModel()
Expand All @@ -256,7 +269,7 @@ public void testMissingCountedModelSet() throws Exception {
.name(UNIT_TEST_COUNTED_FAULT.name())
.configType(ConfigModel.ConfigTypeEnum.FAULT)
.fault(faultModel));
configService.setConfig(groupModel);
assertThrows(ValidationException.class, () -> configService.setConfig(groupModel));
}

private void tryCountedN(int iterations, boolean expected) {
Expand Down
Loading

0 comments on commit b9ff77b

Please sign in to comment.