Issue
Hello I have struglling write a mock test according to my following method below;
my code below;
@Component
public class CodeConfigBuilder {
@Value("${promoConfig.prefix.length}")
private Integer prefixLength;
public void validateRequestAndSetDefaults(PromoRequest promoRequest) {
prefixAndPostFixControlAccordingToLength(promoRequest);
}
private void prefixAndPostFixControlAccordingToLength(PromoRequest promoRequest) {
if (promoRequest.getPostfix() != null) {
int lengthControl = prefixLength + promoRequest.getPostfix().length();
if (lengthControl >= promoRequest.getLength()) {
throw new BadRequestException(Constant.ClientConstants.THE_SUM_OF_PREFIX_AND_POSTFIX_CAN_NOT_BE_GREATER_THAN_LENGHT);
}
}
}
}
my yml configuration below;
#========= Promo Config ========== #
promoConfig:
prefix:
length: 3
my service below;
public void validateRequest(PromoRequest promoRequest) {
codeConfigBuilder.validateRequestAndSetDefaults(promoRequest);
}
I have a created PropertySourceResolver class
@Component
@Getter
public class PropertySourceResolver {
private int prefixLength = 3;
and my test class below;
@RunWith(MockitoJUnitRunner.class)
class CodeConfigBuilderTest {
@MockBean
private PropertySourceResolver propertySourceResolver = new PropertySourceResolver();
@InjectMocks
private PromoRequest promoRequest = new PromoRequest();
@InjectMocks
private PromoService Service;
@Before
public void init() {
promoRequest.setPrefix("ABC");
promoRequest.setPostfix("ABCDABCD");
promoRequest.setQuantity(10);
promoRequest.setLength(12);
promoRequest.setCharset("ABCDEF");
}
@Test
public void prefixAndPostFixControl_accordingToLength_for_Succeed() {
int lengthControl = promoRequest.getPrefix().length() + promoRequest.getPostfix().length();
if (lengthControl >= promoRequest.getLength()) {
Assert.assertTrue(false);
}
}
I like to change my code according to test scenarios like ; when ... then return any idea? thank you.
Solution
To make this simpler and better organize your code, abstract away the complexity of injecting the configurations by creating the following class:
@ConfigurationProperties(prefix = "promoConfig.prefix")
public class PromoPrefixConfiguration {
private Integer length;
public Integer getLength() {
return length;
}
}
Then, you should make this a dependency for CodeConfigBuilder
:
@Component
public class CodeConfigBuilder {
private Integer prefixLength;
public CodeConfigBuilder(PromoPrefixConfiguration promoPrefixConfiguration) {
this.prefixLength = promoPrefixConfiguration.getLength();
}
public void validateRequestAndSetDefaults(PromoRequest promoRequest) {
prefixAndPostFixControlAccordingToLength(promoRequest);
}
private void prefixAndPostFixControlAccordingToLength(PromoRequest promoRequest) {
if (promoRequest.getPostfix() != null) {
int lengthControl = prefixLength + promoRequest.getPostfix().length();
if (lengthControl >= promoRequest.getLength()) {
throw new BadRequestException(Constant.ClientConstants.THE_SUM_OF_PREFIX_AND_POSTFIX_CAN_NOT_BE_GREATER_THAN_LENGHT);
}
}
}
}
Now, in order to test this class you have to do it with three tests:
- Test that
PromoRequest
is valid becausepostfix
is null; - Test that
PromoRequest
is valid because length is valid; - Test that
PromoRequest
is invalid because length is not valid;
They would be something like the following:
class CodeConfigBuilderTest {
private PromoPrefixConfiguration promoPrefixConfiguration = new PromoPrefixConfiguration(10);
private CodeConfigBuilder codeConfigBuilder = new CodeConfigBuilder(promoPrefixConfiguration);
@Test
public void promoRequestIsValidGivenNullPostfix() {
// Arrange
PromoRequest promoRequest = new PromoRequest();
promoRequest.setPostfix(null);
// Act
codeConfigBuilder.validateRequestAndSetDefaults(promoRequest);
}
@Test
public void promoRequestIsValidGivenValidPrefixPlusPostfixLength() {
// Arrange
PromoRequest promoRequest = new PromoRequest();
promoRequest.setPostfix("ABCD");
promoRequest.setLength(15);
// Act
codeConfigBuilder.validateRequestAndSetDefaults(promoRequest);
}
@Test(expected = BadRequestException.class)
public void promoRequestIsInvalidGivenInvalidPrefixPlusPostfixLength() {
// Arrange
PromoRequest promoRequest = new PromoRequest();
promoRequest.setPostfix("ABCDEFGH");
promoRequest.setLength(15);
// Act
codeConfigBuilder.validateRequestAndSetDefaults(promoRequest);
}
}
If you are using JUnit 5, you could replace the last test with the following one to easily assert the exception message:
@Test
public void promoRequestIsInvalidGivenInvalidPrefixPlusPostfixLength() {
// Arrange
PromoRequest promoRequest = new PromoRequest();
promoRequest.setPrefix("ABCDEFG");
promoRequest.setPostfix("HIJKLMN");
// Act
Exception exception = assertThrows(BadRequestException.class, () -> {
codeConfigBuilder.validateRequestAndSetDefaults(promoRequest);
});
// Assert
String exceptionMessage = exception.getMessage();
assertTrue(exceptionMessage.equals(Constant.ClientConstants.THE_SUM_OF_PREFIX_AND_POSTFIX_CAN_NOT_BE_GREATER_THAN_LENGHT));
}
P.S.: do you mean suffix
instead of postfix
?
Answered By - João Dias
Answer Checked By - Candace Johnson (JavaFixing Volunteer)