Skip to content
Advertisement

How to mock my service using Mockito framework

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.

Advertisement

Answer

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:

  1. Test that PromoRequest is valid because postfix is null;
  2. Test that PromoRequest is valid because length is valid;
  3. 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?

Advertisement