I have a problem that prevents me from moving forward and I don't know how to solve it. I have a class called Validator where I store validation functions and I need to do unit tests for each one and validate its functionality, but there are some of them that use the Spring Environment instance in which it accesses the properties file. If I do "normal" unit tests, whenever I call the function where this feature is implemented, it returns me Environment is null. I have tried using @Autowired instead of instantiating with new in the test class, the use of @RunWith(SpringRunner.class) and since the test classes and the function classes are in different packages I have also used the @ComponentScan and it gives me an error... What am I doing wrong or what am I doing wrong?
I have the code of the Validator class in this way:
@Component
public class Validator {
@Autowired
public Environment env;
public CodRespuestaWS validateTypeOperation(TypeOperation typeOperation, String operation) {
String response = env.getProperty(typeOperation.toString() + "." + operation);
if (OK.equalsIgnoreCase(response)) {
return new CodResponseWS();
}
return new CodResponseWS(CodResponseWS.ER100, typeOperation.toString()+" not allowed:" + operation);
}
}
And in the test I do it this way:
@ComponentScan(basePackages = "com.functions.validators")
@RunWith(SpringRunner.class)
public class ValidateRequestHigh {
RequestHigh requestHigh = new RequestHigh();
CodResponseWS response;
@Autowired Validator validator;
HighValidator highValidator = new HighValidator();
UserData userData = new UserData();
@Test
public void test() throws Exception {
response = validator.validateTypeOperation(TypeOperation.typeOperationHigh, "high");
System.out.println(response.getCodResponse());
}
}
The problem that I mentioned before the NULL, is that when executing the test it did not even reach the print that I have set, but rather it stayed on the line
String response = env.getProperty(typeOperation.toString() + "." + operation);
And it marked the error that env was NULL and now it returns a different one
And the error that returns me now is:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'functiontest.unittest.ValidateRequestHighTest': Unsatisfied dependency expressed through field 'validator'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.functions.validators.Validator' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
I guess it's already understood, but I'll detail it more just in case, the functions are in
src/main/java/com.functions.validators/Validators.java
and the tests
src/main/test/functiontest.unittest/ValidateRequestHighTest.java
I am using version 5.1.2.RELEASE of SpringBoot and JUnit 4
Using field injection makes Validator
class impossible to be unit tested because it provides no way to pass the Environment
instance to it. but you can spin up the whole application context and configure it to do dependency injection stuff using @SpringBootTest
which is not a unit test but integration test.
if I do "normal" unit tests, whenever I call the function where this feature is implemented, it returns me Environment is null.
Because when you use new
to instantiate a bean its not a Spring managed bean anymore and its dependencies are not resolved.
I have tried using @Autowired instead of instantiating with new in the test class, the use of @RunWith(SpringRunner.class) and since the test classes and the function classes are in different packages I have also used the @ComponentScan and it gives me an error
You should also add SpringBootTest
annotation for loading into application context.
If you want to really unit test your class you don't need application context instead do the following
Change the Validator
class like:
@Component
public class Validator {
private Environment env;
public Validator(Environment env) {
this.env = env;
}
....
}
And for unit testing it do:
public class ValidatorTest {
Validator validator;
MockEnvironment environment;
@Before
public void setUp() {
environment = new MockEnvironment();
environment.setProperty("key1", "value1");
//...
environment.setProperty("keyn", "valuen");
validator = new Validator(environment);
}
@Test
public void test() {
// test stuff
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.