We do #Autowired NamedParameterJdbcTemplate in Spring Boot 2 and it works OK. This works because NamedParameterJdbcTemplate is in applicationContext? - spring

I checked whether NamedParameterJdbcTemplate is in the applicationConext using the code below.
But it does not find it. Any idea?
private static ApplicationContext applicationContext;
public static void main(String[] args) {
applicationContext = SpringApplication.run(ApplicationLauncher.class, args);
Object obj = applicationContext.getBean("namedParameterJdbcTemplate");
}
}

Related

Spring #JpaDataTest no transaction

I'm tring to use #JpaDataTest to test my repository
I'm use it like:
#RunWith(SpringRunner.class)
#DataJpaTest
public class MyTest {
#Autowired
private TestEntityManager entityManager;
#Autowired
private MyRepo myRepo;
#Test
public void myTest() {
assertEquals(0, myRepo.findAll().size());
entityManager.persist(new MyEntity());
//entityManager.flush();
assertEquals(1, myRepo.findAll().size());
}
}
Test doesn't pass because of the second findAll return 0 entity
If i remove the commentary to flush
i got an error
javax.persistence.TransactionRequiredException: no transaction is in progress
I find why...
#SpringBootConfiguration
#EnableAutoConfiguration
#ComponentScan
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
if i remove #ComponentScan it works...

How to do unit test for spring boot auto configuration

In a spring boot auto configuration project there are two emailSender child classes: MockEmailSender and TextEmailSender. And in auto configuration only one mailSender should be created:
#Bean
#ConditionalOnMissingBean(MailSender.class)
#ConditionalOnProperty(name="spring.mail.host", havingValue="foo", matchIfMissing=true)
public MailSender mockMailSender() {
log.info("Configuring MockMailSender");
return new MockMailSender();
}
#Bean
#ConditionalOnMissingBean(MailSender.class)
#ConditionalOnProperty("spring.mail.host")
public MailSender smtpMailSender(JavaMailSender javaMailSender) {
log.info("Configuring SmtpMailSender");
return new SmtpMailSender(javaMailSender);
}
following is my unit test code:
#SpringBootApplication
public class LemonTest implements ApplicationContextAware{
private ApplicationContext context;
public static void main(String[] args){
SpringApplication.run(LemonTest.class, args);
System.out.println("haha");
}
#Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context = applicationContext;
}
}
#RunWith(SpringRunner.class)
#SpringBootTest
public class InitTest {
#Autowired
private MailSender mailSender;
#Test
public void test(){
assertNotNull(mailSender);
}
}
And the properties are
spring.mail.host=foo
spring.mail.port=587
spring.mail.username=alert1
spring.mail.password=123456
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
Based on my auto configuration only MockEmailSender should be initialized,
but both emailSender bean are created, so multiple bean error is thrown when running the unit test. I guess my configuration settings are not loaded by the test.
So how to include the auto configuration in the test? what would be the best practices to test auto configuration?
I've always created multiple tests using separate "profiles" to control what is loaded/set, setting the active profile on the test.
#ActiveProfiles({ "test", "multipleemail" })
Then your test would ensure the expected result (multiple email providers in context, etc).
Properties can be imported if you need separate ones. I store one in src/test specifically for my unit tests.
#PropertySource({ "classpath:sparky.properties" })
I finally solve it. Just add #Import(LemonAutoConfiguration.class) to the application.
#SpringBootApplication
#Import(LemonAutoConfiguration.class)
public class LemonTest implements ApplicationContextAware{
private ApplicationContext context;
public static void main(String[] args){
SpringApplication.run(LemonTest.class, args);
System.out.println("haha");
}
#Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context = applicationContext;
}
}

Not able to mock jdbcTemplate in Spring boot Test class

I am using Spring boot and Mockito for testing. I have been able to write test cases for Service layer and they re working fine. But, the test cases for DAO layer do not. The jdbcTemplate object that is mocked and autowired gives null pointer when executing the test case. Below are the details:
My DAOTest class:
#RunWith(SpringRunner.class)
#SpringBootTest(classes = EcommerceApplication.class)
public classEcommerceDaoTest {
#InjectMocks
private IEcommerceDao ecommerceDao = new EcommerceDaoImpl();
#Mock
#Autowired
private JdbcTemplate as400JdbcTemplate;
#Before
public void setUp() throws Exception
{
MockitoAnnotations.initMocks(this);
}
#Test
public void checkOrderExistsTest() throws EcommerceException{
Mockito.when(as400JdbcTemplate.queryForObject(queryForOrder,new Object[]
{"1000"}, int.class)).thenReturn(1);
boolean exists =
ecommerceDao.checkOrderExists("1000");
assertTrue(exists);
}
}
EcommerceDAOImpl.java:
#Override
public boolean checkOrderExists(String orderNo)throws EcommerceException{
boolean doesExist = false;
int count = 0;
try{
count= as400JdbcTemplate.queryForObject(queryForOrder, new Object[]{orderNo}, int.class);
if(count >0){
doesExist = true;
}
}
catch(Exception e){
}
return doesExist;
}
AS400Config.java:
#Bean
#Autowired
public JdbcTemplate as400JdbcTemplate(#Qualifier("as400DataSource")DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
ECommerceApplication.java
#SpringBootApplication(exclude = { DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class })
#EnableTransactionManagement
#Import(As400Configuration.class)
public class EcommerceApplication {
public static void main(String[] args) {
SpringApplication.run(EcommerceApplication.class, args);
}
}
When I am running the test case, I am getting NullPointerException for as400JdbcTemplate. The functionality works fine as is. Its just the test cases for DAO layer that fail because of the inability of the jdbcTemplate to get mocked/autowired.
Please let me know where I am going wrong.
You don't need to use #Mock and #Autowired at the same time. Use only #Mock:
#Mock
private JdbcTemplate as400JdbcTemplate;
Use instead of #RunWith(SpringRunner.class) --> #RunWith(MockitoJUnitRunner.class)
Also to inject mock into DAO you can use ReflectionTestUtils from spring test.
public static void setField(Class targetClass, String name, Object value)
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
ReflectionTestUtils.setField(ecommerceDao ,"as400JdbcTemplate" ,
as400JdbcTemplate);
}
#Mock
private JdbcTemplate as400JdbcTemplate;

Standalone Spring/Mybatis application autowiring returns null

So I'm trying to write a standalone application using Spring and Mybatis. I used the same DAO's and stuff for a web application, and everything works fine. I want to be able to reuse as much of that code as possible to automate a process. I need to autowire a DAO and use it from a main() method. Right now, I have it modeled somewhat off of this question: Autowiring a Spring 3.2 standalone application fails so I have something like
public class Main{
#Autowired
DAO dao;
public Main(){
final ApplicationContext context = new FileSystemXmlApplicationContext("src/beans.xml");
AutowireCapableBeanFactory acbFactory = context.getAutowireCapableBeanFactory();
acbFactory.autowireBean(this);
System.out.println(dao);
}
public static void main(String[] args) throws Exception {
Main m = new main();
}
The output is null. My DAO file is an interface and the implemented interface has something like
#Repository
#Component
public class DAOImpl implements DAO{
#Autowired
mapper m;
//some methods
}
How do I get it to autowire properly?
EDIT: As suggested, I tried doing this:
public class Main{
#Autowired
DAO dao;
public Main(){
}
public static void main(String[] args) throws Exception {
Main m = new main();
final ApplicationContext context = new FileSystemXmlApplicationContext("src/beans.xml");
AutowireCapableBeanFactory acbFactory = context.getAutowireCapableBeanFactory();
acbFactory.autowireBean(m);
System.out.println(m.dao);
}
It still prints out null

How to use the appicationcontextaware in java class

I need to load the applicationcontext in java class in which the applicationcontextaware bean is defined. I need to access the other beans inside the applicationcontext.xml using the applicationcontextaware. I dont want to load the context using
ClassPathXmlApplicationContext("applicationContext.xml");
I need to access the beans inside the applicationContext like this
ApplicationContextAccess.getInstance().getApplicationContext.getbean("BeanName");
Applicationcontextacess implemented as singleton class:
public class ApplicationContextAccess implements ApplicationContextAware {
private ApplicationContext applicationContext = null;
private static ApplicationContextAccess applicationContextAccess=null;
private ApplicationContextAccessor() {
}
public static synchronized ApplicationContextAccess getInstance() {
if(applicationContextAccess == null)
{
applicationContextAccess = new ApplicationContextAccess();
}
return applicationContextAccess;
}
public void ApplicationContext getApplicationContext() {
return applicationContext;
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
applicationContext = applicationContext;
}
}
I need to access the beans inside the applicationContext like this ApplicationContextAccess.getInstance().getApplicationContext.getbean("BeanName");
But I have a doubt how the getApplicationContext loads the applicationContext.xml........?

Resources