Reputation: 2123
I've generated a Spring Boot web application using Spring Initializr, using embedded Tomcat + Thymeleaf template engine, and package as an executable JAR file.
Technologies used :
Spring Boot 1.4.2.RELEASE, Spring 4.3.4.RELEASE, Thymeleaf 2.1.5.RELEASE, Tomcat Embed 8.5.6, Maven 3, Java 8
I have this class I have this junit test class:
@ContextConfiguration(classes={TestPersistenceConfig.class})
@RunWith(SpringRunner.class)
@SpringBootTest
public class JdbcRemoteUnitRepositoryTests {
@Autowired
private JdbcRemoteUnitRepository repository;
@Autowired
@InjectMocks
private SmsConfig smsConfig;
@Autowired
@InjectMocks
private NextelSMSSender smsService;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
@Test
public void testGetAllUnits() throws DataAccessException, SQLException {
Assert.assertTrue(true);
}
}
the class NextelSMSSender:
@Service("smsService")
public class NextelSMSSender {
public final static String OK_STATUS_CODE = "200";
@Autowired
SmsConfig smsConfig;
..
}
.
@Configuration
@PropertySource("sms-gateway.properties")
public class SmsConfig {
@Value("${sms.domainId}")
private String domainId;
@Value("${sms.gateway.url}")
private String gatewayUrl;
..
}
But it seems that is not mocking the objects property, because when I package the app. I got this error:
***************************
APPLICATION FAILED TO START
***************************
Description:
Field smsConfig in com.plats.bruts.NextelSMSSender required a bean of type 'com.plats.bruts.config.SmsConfig' that could not be found.
Action:
Consider defining a bean of type 'com.plats.bruts.config.SmsConfig' in your configuration.
I created a mock bean named TestSmsConfig
, tried to add @Bean
, but I got a compilation error:
The annotation @Bean is disallowed for this
location
@Configuration
@Bean
public class TestSmsConfig {
@Value("fake.domainId")
private String domainId;
@Value("fake.sms.gateway.url")
private String gatewayUrl;
...
}
Upvotes: 2
Views: 1451
Reputation: 406
OK, so this is your configuration:
@Configuration
@PropertySource("sms-gateway.properties")
public class SmsConfig {
@Value("${sms.domainId}")
private String domainId;
@Value("${sms.gateway.url}")
private String gatewayUrl;
..
}
If you want to use that configuration in your test, you should add it to your configuration classes...
@ContextConfiguration(classes={TestPersistenceConfig.class, SmsConfig.class})
And not add it as @Autowired or whatever.
Upvotes: 0
Reputation: 2104
You're autowiring smsConfig, but you do not appear to provide that @Bean in your test application context.
In addition, you are using @InjectMocks incorrectly - this should be used to inject mock objects into the class under test (your NextelSMSSender class, not SmsConfig).
To resolve, add a @Bean method in your configuration class to provide SmsConfig bean instances.
Replace @InjectMocks from the SmsConfig variable in your test class with @MockBean. SmsConfig is an autowired mock object, and not the class under test.
See Section 41.3.4 - Of the Spring Boot Testing Features for more info:
Spring Boot includes a @MockBean annotation that can be used to define a Mockito mock for a bean inside your ApplicationContext. You can use the annotation to add new beans, or replace a single existing bean definition. The annotation can be used directly on test classes, on fields within your test, or on @Configuration classes and fields. When used on a field, the instance of the created mock will also be injected. Mock beans are automatically reset after each test method.
Upvotes: 1