Springboot test not loading properties from application.yml

Viewed 102

I have a springboot test case trying to test a method which has some dependency on env properties.

@SpringBootTest(classes = ABCApi.class)
@AutoConfigureMockMvc
class sampleTest {

  @Autowired
  private WebApplicationContext context;

  protected MockMvc mockMvc;

  @BeforeEach
  public void setup() {
    mockMvc = MockMvcBuilders
            .webAppContextSetup(context)
            .apply(SecurityMockMvcConfigurers.springSecurity())
            .build();
  }

  @InjectMocks
  private EmployeeServiceImpl employeeServiceImpl;

  @Test
  void testEmployeeServiceImpl() {
    String summary = "summary";
    String description = "description";
    String response = employeeServiceImpl.createIssue(summary, description);
    verify(EmployeeService, times(1)).createIssue(summary, description);
  }
}

Note: I don't need to test the response. All I need is to make sure that the method is called. The response will be null because of some unavailable parameters.

Below is the EmployeeServiceImpl code which has all properties listed. I have the application.yml file in src/test/resources, which is the right location. But while debugging the test case above, the below class is not loading any properties from application.yml sitting in test folder structure.

@Service
public class EmployeeServiceImpl {

  @Value("${emp.username}")
  private String username;
  @Value("${emp.password}")
  private String password;
  @Value("${emp.url}")
  private String url;
  
  @Override
  public String createIssue(String summary, String description) {
    EmpRestClient client = setEmpClient();
    EmpSuperClient empSuperClient = client.getProject();
    IssueInput newIssue = buildNewIssueInput(description, summary);
    return empSuperClient.createIssue(newIssue).claim().getKey();
  }

  private EmpRestClient setEmpClient() {
    return new EmpRestClientFactory()
            .createWithBasicHttpAuthentication(URI.create(url), username, password);
  }

I know that these properties are not supposed to be in service layer and instead should be loaded as a bean in config class which will be a future improvement.

How do I fix that test case?

1 Answers

Use constructor injection to inject dependencies. It makes code easy to test.

private final String username;
private final String password;
private final String url;

public EmployeeServiceImpl (@Value("${emp.username}") final String username, @Value("${emp.password}") final String password,
      @Value("${emp.url}") String url) {

    this.username = username;
    this.password = password;
    this.url = url;
  }

Now you can use the constructor to create EmployeeServiceImpl in your test class.

E.g.

new EmployeeServiceImpl ("username", "password", "http://localhost:8080")
Related