Skip to content

Commit

Permalink
Add Unit tests to Conditional on Profile
Browse files Browse the repository at this point in the history
- Ignores order of profile
- validates value attribute
- Works only with more than one profile
  • Loading branch information
shyamz-22 committed Dec 16, 2017
1 parent 74e12ba commit f4fee62
Show file tree
Hide file tree
Showing 7 changed files with 207 additions and 106 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Conditional(ActiveOnProfilesCondition.class)
public @interface ConditionalOnProfiles {
String[] value() default {};
}
@Conditional(ConditionalOnAllProfilesCondition.class)
public @interface ConditionalOnAllProfiles {
String[] value();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package io.github.shyamz.conditional;


import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;


public class ConditionalOnAllProfilesCondition implements Condition {

private List<String> currentProfiles = new ArrayList<>();
private List<String> activeProfiles = new ArrayList<>();

@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Map<String, Object> attributes = metadata
.getAnnotationAttributes(ConditionalOnAllProfiles.class.getName());

populateCurrentProfiles((String[]) attributes.get("value"));
populateActiveProfiles(context.getEnvironment().getActiveProfiles());

return currentProfiles.stream().allMatch(activeProfiles::contains);
}

private void populateCurrentProfiles(String[] attributeValues) {
currentProfiles.clear();
currentProfiles.addAll(Arrays.asList(attributeValues));
validateCurrentProfiles();
}

private void validateCurrentProfiles() {
if (currentProfiles.isEmpty() || currentProfiles.size() == 1) {
throw new RuntimeException("'value' attributes need more than one 'profile' values. For just one profile use '@Profile' annotation");
}
}

private void populateActiveProfiles(String[] activeProfileValues) {
activeProfiles.clear();
activeProfiles.addAll(Arrays.asList(activeProfileValues));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,46 +10,20 @@
@SpringBootApplication
public class ConditionalApplication {

@Bean
@ConditionalOnAllProfiles(value = {"A", "B"})
@Primary
public ConditionalBean conditionalOnAB() {
return () -> "AB";
}

@Bean
@ConditionalOnProfiles(value = {"A", "B"})
@Primary
public ConditionalBean conditionalOnAB()
{
return new ConditionalBean() {
@Override
public String getValue() {
return "AB";
}
};
}
@Bean
@Profile(value = {"A"})
public ConditionalBean conditionalOnA() {
return () -> "A";
}

@Bean
@ConditionalOnProfiles
@Primary
public ConditionalBean conditionalOnDefault()
{
return new ConditionalBean() {
@Override
public String getValue() {
return "Default";
}
};
}

@Bean
@Profile(value = {"A"})
public ConditionalBean conditionalOnA()
{
return new ConditionalBean() {
@Override
public String getValue() {
return "A";
}
};
}

public static void main(String[] args) {
SpringApplication.run(ConditionalApplication.class, args);
}
public static void main(String[] args) {
SpringApplication.run(ConditionalApplication.class, args);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package io.github.shyamz.conditional;

import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.mock.env.MockEnvironment;
import org.springframework.util.MultiValueMap;

import java.util.Collections;
import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;


public class ConditionalOnAllProfilesConditionTest {

private ConditionalOnAllProfilesCondition subject;

@Before
public void setUp() throws Exception {
subject = new ConditionalOnAllProfilesCondition();
}

@Test
public void throwsExceptionForEmptyProfileList() throws Exception {
assertThatThrownBy(
() -> subject.matches(mockConditionContext(), mockAnnotatedTypeMetaData()))
.isExactlyInstanceOf(RuntimeException.class)
.hasMessage("'value' attributes need more than one 'profile' values. For just one profile use '@Profile' annotation");
}

@Test
public void throwsExceptionForOneProfile() throws Exception {
assertThatThrownBy(
() -> subject.matches(mockConditionContext(), mockAnnotatedTypeMetaData("test")))
.isExactlyInstanceOf(RuntimeException.class)
.hasMessage("'value' attributes need more than one 'profile' values. For just one profile use '@Profile' annotation");
}

@Test
public void returnsTrueIfCurrentProfilesAreEqual() throws Exception {
assertThat(subject.matches(mockConditionContext("test", "local"),
mockAnnotatedTypeMetaData("test", "local"))).isTrue();
}

@Test
public void returnsTrueIfCurrentProfilesAreEqualButInDifferentOrder() throws Exception {
assertThat(subject.matches(mockConditionContext("test", "local"),
mockAnnotatedTypeMetaData("local", "test"))).isTrue();
}

@Test
public void returnsTrueIfCurrentProfilesAreSubsetOfActiveProfiles() throws Exception {
assertThat(subject.matches(mockConditionContext("test", "local", "pact"),
mockAnnotatedTypeMetaData("local", "test"))).isTrue();
}

@Test
public void returnsFalseIfCurrentProfilesAreNotSubsetOfActiveProfiles() throws Exception {
assertThat(subject.matches(mockConditionContext("test", "local"),
mockAnnotatedTypeMetaData("local", "test", "pact"))).isFalse();
}

@Test
public void returnsFalseIfCurrentProfilesAreDifferent() throws Exception {
assertThat(subject.matches(mockConditionContext("test", "local"), mockAnnotatedTypeMetaData("cloud", "acceptance"))).isFalse();
}

private ConditionContext mockConditionContext(String... activeProfiles) {
return new ConditionContext() {

@Override
public BeanDefinitionRegistry getRegistry() {
return null;
}

@Override
public ConfigurableListableBeanFactory getBeanFactory() {
return null;
}

@Override
public Environment getEnvironment() {
MockEnvironment environment = new MockEnvironment();
environment.withProperty("spring.profiles.active", String.join(",", activeProfiles));
return environment;
}

@Override
public ResourceLoader getResourceLoader() {
return null;
}

@Override
public ClassLoader getClassLoader() {
return null;
}
};

}

private AnnotatedTypeMetadata mockAnnotatedTypeMetaData(String... currentProfiles) {
return new AnnotatedTypeMetadata() {
@Override
public boolean isAnnotated(String annotationName) {
return true;
}

@Override
public Map<String, Object> getAnnotationAttributes(String annotationName) {
return Collections.singletonMap("value", currentProfiles);
}

@Override
public Map<String, Object> getAnnotationAttributes(String annotationName, boolean classValuesAsString) {
return null;
}

@Override
public MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName) {
return null;
}

@Override
public MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName, boolean classValuesAsString) {
return null;
}
};
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
@ActiveProfiles({"A"})
public class DefaultSpringProfileBehaviorTests {

@Autowired
ConditionalBean conditionalBean;
@Autowired
private ConditionalBean conditionalBean;

@Test
public void generatesConditionalBeanA_whenOnlyProfileAIsActive() {
assertThat(conditionalBean.getValue(), equalTo("A"));
}
@Test
public void generatesConditionalBeanA_whenOnlyProfileAIsActive() {
assertThat(conditionalBean.getValue(), equalTo("A"));
}

}

0 comments on commit f4fee62

Please sign in to comment.