Getting BadRequestException in JUnit using Mockito - junit

I'm writing a Junit for a service class using Mockito. Application has been built up using Java 8, Spring 5. While my rest of test methods are running fine except this one where I'm stuck and unable to proceed further.
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = CommerceConnectorApplication.class)
#ActiveProfiles("test")
#AutoConfigureWebTestClient
public class CommerceRepositoryDetailsTest {
#Autowired
private RepositoryDetails repositoryDetails;
#MockBean
private AsyncRunner asyncRunner;
#MockBean
private CommerceTenantUserRepository tenantUserRepository;
#Test
public void whenUpdateCartId_ThenReturnUpdatedTenantUserDetails(){
String tenantId = "2737363";
String userId = "763sssj";
String cartId = "827";
TenantUserKey tenantUserKey = new TenantUserKey();
tenantUserKey.setTenantId(tenantId);
tenantUserKey.setUserId(userId);
CommerceTenantUser commerceTenantUser = new CommerceTenantUser(tenantUserKey, "xyz#abc.com", cartId, LocalDate.now());
Optional <CommerceTenantUser> commerceTenantUser1 = Optional.of(commerceTenantUser);
Mockito.when(tenantUserRepository.findById(tenantUserKey)).thenReturn(commerceTenantUser1);
Mono<CommerceTenantUser> actualMono = repositoryDetails.updateCartId(tenantId, userId, cartId);
CommerceTenantUser commerceTenantUser2 = actualMono.block();
assertThat(commerceTenantUser2, is(commerceTenantUser));
}
}
Error :-
2018-08-14 16:19:38.843 INFO 106888 --- [ main] c.s.c.c.c.s.CommerceRepositoryDetails : Entering updateCartId#CommerceSystemDetailService
com.sap.chatbot.commerceconnector.exception.BadRequestException: error in updating cart
at com.sap.chatbot.commerceconnector.common.security.CommerceRepositoryDetails.updateCartId(CommerceRepositoryDetails.java:139)
at com.sap.chatbot.commerceconnector.common.security.CommerceRepositoryDetails$$FastClassBySpringCGLIB$$fd3bfefe.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.cache.interceptor.CacheInterceptor.lambda$invoke$0(CacheInterceptor.java:53)
at org.springframework.cache.interceptor.CacheAspectSupport.invokeOperation(CacheAspectSupport.java:337)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:392)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:317)
at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at com.sap.chatbot.commerceconnector.common.security.CommerceRepositoryDetails$$EnhancerBySpringCGLIB$$3b388d4d.updateCartId(<generated>)
at com.sap.chatbot.commerceconnector.CommerceRepositoryDetailsTest.whenUpdateCartId_ThenReturnUpdatedTenantUserDetails(CommerceRepositoryDetailsTest.java:124)
The main method to test :-
#Override
#CachePut(value = CommerceConnectorConstants.CommerceCache.COMMERCE_CACHE_TENANT_USER_DATA_MAP)
public Mono<CommerceTenantUser> updateCartId(String tenantId, String userId, String cartId) {
logger.info("Entering updateCartId#CommerceSystemDetailService");
final TenantUserKey commerce = getTenantUserObj(tenantId, userId);
Optional<CommerceTenantUser> tenantUser = commerceTenantUserRepository.findById(commerce);
return tenantUser.map(tenantUserObj -> updateCartIdAndRefreshMap(tenantUserObj, cartId))
.orElse(Mono.error(new BadRequestException("error in updating cart")));
}
private Mono<CommerceTenantUser> updateCartIdAndRefreshMap(CommerceTenantUser tenantUserObj, String cartId) {
tenantUserObj.setCartId(cartId);
final Mono<CommerceTenantUser> commerceTenantUser = asyncRunner
.one(() -> commerceTenantUserRepository.saveAndFlush(tenantUserObj))
.doOnNext(value -> commerceCacheService.refreshMap())
.doOnError(error -> Mono.error(new BadRequestException("Error ocurred in updating cart id ")))
.map(commerceTenantUserObj -> commerceTenantUserObj);
return commerceTenantUser;
}
The method updateCartId() calls another private method updateCartIdAndRefreshMap(). My JUnit fails in return statment in updateCartId().
Please advise on how to fix my JUnit to test this specific updateCartId() method.

Related

Spring Batch read DB2 write Mysql duplicated records in Resultset

I'm trying to read from DB2 with a stored procedure ( SP ) that returns records based on page size and start page among other input parameters. My goal is however to request all the records in one call and load another table in Mysql using Spring Batch. Seems straight forward enough, however when I run the job below it returns the correct number of records as per the SP but the records are skewed and duplicated as if the transactions are not working properly. The reader uses one #Primary Datasources ( DS ), for the DB2 read and another DS for the JpaItemWriter destination (LocalContainerEntityManagerFactoryBean).
My understanding is that DB2 and Mysql returns a ResultSet so don't know why I am forced to add these lines to avoid Invalid Parameter Type or Cursor position errors....
reader.setVerifyCursorPosition(false);
reader.setRefCursorPosition(0);
I am reading from DB2 then inserting into a MySql table based on the supplied AccountCashRowMapper. It's a strange situation that almost works, the listener doesn't report any errors.
Spring Batch is supposed to inherently manage the transactions for me, however what configuration or code is missing to make this work ?
#EnableBatchProcessing
public class LoadAccountCashTableJob {
private static final Logger logger = LoggerFactory.getLogger(LoadAccountCashTableJob.class);
#Autowired
ApplicationContext context;
#Autowired
public AccountCashRepository repo;
#Autowired
public EntityManager em;
#Autowired
private JobBuilderFactory jobBuilderFactory;
#Autowired
private StepBuilderFactory stepBuilderFactory;
#Autowired
private AccountCashProcessor accountCashProcessor;
#Autowired
private TaskExecutor taskExecutor;
#Autowired
#Qualifier("originDataSource")
protected DataSource dataSource;
#Qualifier(value = "AccountCashJob")
#Bean
public Job AccountCashJob() throws Exception{
return this.jobBuilderFactory.get("AccountCashJob")
.start(this.accountCashStep())
.build();
}
#Bean
public Step accountCashStep() throws Exception{
return this.stepBuilderFactory.get("accountCashStep")
//.transactionManager(transactionManager)
.<String, String>chunk(500)
.reader(this.cashSPReader(dataSource))
.processor(accountCashProcessor)
.writer(this.accountCashItemWriter() )
.taskExecutor(taskExecutor)
.listener(new ItemFailureLoggerListener())
.build();
}
#Bean(destroyMethod="")
#StepScope
public StoredProcedureItemReader cashSPReader (DataSource dataSource) throws Exception {
StoredProcedureItemReader reader = new StoredProcedureItemReader();
SqlParameter[] parameters = new SqlParameter[7];
parameters[0] = new SqlParameter("DIV", Types.VARCHAR);
parameters[1] = new SqlParameter("PageDebut", Types.SMALLINT);
parameters[2] = new SqlParameter("NbParPage",Types.SMALLINT);
parameters[3] = new SqlInOutParameter("O_NB_PAGES",Types.SMALLINT);
parameters[4] = new SqlInOutParameter("O_RC",Types.INTEGER);
parameters[5] = new SqlInOutParameter("O_RC_DSC",Types.VARCHAR);
parameters[6] = new SqlReturnResultSet(ACCOUNTCASH_RESULT_SET, new AccountCashRowMapper());
reader.setDataSource(dataSource);
reader.setProcedureName("VMDTSTSP.db2cdb_List_Positions_Encaisse");
reader.setRowMapper(new AccountCashRowMapper()); //FOR the output records..
reader.setParameters(parameters);
reader.setPreparedStatementSetter(new SPParamSetter());
reader.afterPropertiesSet();
logger.info("reader.getSql()>>>>>>>>>>>>>>"+reader.getSql());
reader.setVerifyCursorPosition(false);
reader.setRefCursorPosition(0);
return reader;
}
#Bean(destroyMethod="")
#StepScope
public JpaItemWriter<AccountCash> accountCashItemWriter() {
EntityManagerFactory emf = (EntityManagerFactory) context.getBean("entityManagerFactory");
em.createNativeQuery("TRUNCATE TABLE purefacts.account_cash").executeUpdate();
JpaItemWriter<AccountCash> accountCashJpaItemWriter = new JpaItemWriter<>();
accountCashJpaItemWriter.setEntityManagerFactory(emf);
accountCashJpaItemWriter.setUsePersist(true);
return accountCashJpaItemWriter;
}
public static class SPParamSetter implements PreparedStatementSetter {
#Override
public void setValues(PreparedStatement ps) throws SQLException {
AS400JDBCCallableStatement eventCallableSt=(AS400JDBCCallableStatement)ps;
eventCallableSt.setString(1, ACCOUNTCASH_DIV);
eventCallableSt.setInt(2, ACCOUNTCASH_START_PAGE);
eventCallableSt.setInt(3,ACCOUNTCASH_PAGE_SIZE);
eventCallableSt.registerOutParameter(4, Types.SMALLINT);
eventCallableSt.setInt(4, ACCOUNTCASH_O_NB_PAGES);
eventCallableSt.registerOutParameter(5, Types.INTEGER);
eventCallableSt.setInt(5, ACCOUNTCASH_O_ERROR_CODE);
eventCallableSt.registerOutParameter(6, Types.VARCHAR);
eventCallableSt.setString(6, ACCOUNTCASH_O_ERROR_DESCRIPTION);
eventCallableSt.getResultSet();
}
}
public class ItemFailureLoggerListener extends ItemListenerSupport {
private Log logger = LogFactory.getLog("item.error");
public void onReadError(Exception e) {
logger.error("Encountered error on read", e);
}
public void onWriteError(Exception ex, List items) {
logger.error("Encountered error on write", ex);
}
}
}

Unable to mock a method

I am new to JUNITS and have been trying to use Mockito and PowerMockito for writing some test cases for my code but have been facing an issue.
Class Code:
public class Example implements Callable<Void> {
int startIndex;
int endIndex;
ConnectionPool connPool;
Properties properties;
public Example(int start, int end,
ConnectionPool connPool, Properties properties) {
this.startIndex = start;
this.endIndex = end;
this.connPool= connPool;
this.properties = properties;
}
#Override
public Void call() throws Exception {
long startTime = System.currentTimeMillis();
try {
List<String> listInput = new ArrayList<>();
Service service = new Service(
dbConnPool, properties, startIndex, endIndex);
service.getMethod(listInput);
.
.
.
JUNIT Code:
#RunWith(PowerMockRunner.class)
#PrepareForTest()
public class ExampleTest {
#Mock
private ConnectionPool connectionPool;
#Mock
private Properties properties;
#Mock
private Service service = new Service(
connectionPool, properties, 1, 1);
#Mock
private Connection connection;
#Mock
private Statement statement;
#Mock
private ResultSet resultSet;
#InjectMocks
private Example example = new Example(
1, 1, connectionPool, properties);
#Test
public void testCall() throws Exception {
List<String> listInput= new ArrayList<>();
listInput.add("data1");
when(service.getMethod(listInput)).thenReturn(listInput);
example.call();
}
Question: How to mock Service class and its method, getMethod, call ?
Explanation: The Service class has method getMethod, which is interacting with the DB. So, as I am not able to mock this method, the code goes through and then I have to mock all the objects in the getMethod as connection, resultset etc. else it throws NullPointerException.
Please help me understand what I am doing wrong and if possible provide your guidance on the way I should approach the JUNITS for this kind of method call.
Mockito won't help you to mock an object if you have calling of new Service inside of your method.
Instead you need to use PowerMock.expectNew
Service mockService = PowerMock.createMock(Service.class);
PowerMock.expectNew(Service.class, connectionPool, properties, 1, 1)
.andReturn(mockService);
PowerMock.replay(mockService);
For PowerMockito there is an equivalent:
PowerMockito.whenNew(Service.class)
.withArguments(connectionPool, properties, 1, 1)
.thenReturn(mockService);
Please check this article.

Spring Boot Hikari Multiple Database Autowiring Failing

I am trying to implement multiple database with Spring Boot Hikari CP. I am getting
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] is defined: expected single matching bean but found 2: hikari_primary,hikari_secondary
For your reference I am attaching my spring boot datasource configuration files,
please dont go over primary and secondary naming conventions(they dont represent priorities), my requirement it to have two connection pool for two different databases.
Any help is appreciated
1.application.properties
spring.datasource.dataSourceClassName=com.microsoft.sqlserver.jdbc.SQLServerDataSource
primary.spring.datasource.url=jdbc:sqlserver://xxx.xxx.xxx.xxx:1433;DatabaseName=training
primary.spring.datasource.username=training
primary.spring.datasource.password=training
primary.spring.datasource.poolName=hikari_primary
primary.spring.datasource.maximumPoolSize=5
primary.spring.datasource.minimumIdle=3
primary.spring.datasource.maxLifetime=2000000
primary.spring.datasource.connectionTimeout=30000
primary.spring.datasource.idleTimeout=30000
primary.spring.datasource.pool-prepared-statements=true
primary.spring.datasource.max-open-prepared-statements=250
secondary.spring.datasource.url=jdbc:sqlserver://xxx.xxx.xxx.xxx:1433;DatabaseName=dev_xxxxx_core_v3
secondary.spring.datasource.username=developer
secondary.spring.datasource.password=Developer
secondary.spring.datasource.poolName=hikari_secondary
secondary.spring.datasource.maximumPoolSize=50
secondary.spring.datasource.minimumIdle=30
secondary.spring.datasource.maxLifetime=2000000
secondary.spring.datasource.connectionTimeout=30000
secondary.spring.datasource.idleTimeout=30000
secondary.spring.datasource.pool-prepared-statements=true
secondary.spring.datasource.max-open-prepared-statements=300
2. PrimaryDataSourceConfig.java
#Configuration
public class PrimaryDataSourceConfig {
#Value("${primary.spring.datasource.username}")
private String user;
#Value("${primary.spring.datasource.password}")
private String password;
#Value("${primary.spring.datasource.url}")
private String dataSourceUrl;
#Value("${spring.datasource.dataSourceClassName}")
private String dataSourceClassName;
#Value("${primary.spring.datasource.poolName}")
private String poolName;
#Value("${primary.spring.datasource.connectionTimeout}")
private int connectionTimeout;
#Value("${primary.spring.datasource.maxLifetime}")
private int maxLifetime;
#Value("${primary.spring.datasource.maximumPoolSize}")
private int maximumPoolSize;
#Value("${primary.spring.datasource.minimumIdle}")
private int minimumIdle;
#Value("${primary.spring.datasource.idleTimeout}")
private int idleTimeout;
#Bean(name="hikari_primary")
public HikariDataSource getHikariDataSourcePrimary() {
Properties dsProps = new Properties();
dsProps.put("url", dataSourceUrl);
dsProps.put("user", user);
dsProps.put("password", password);
Properties configProps = new Properties();
configProps.put("dataSourceClassName", dataSourceClassName);
configProps.put("poolName", poolName);
configProps.put("maximumPoolSize", maximumPoolSize);
configProps.put("minimumIdle", minimumIdle);
configProps.put("minimumIdle", minimumIdle);
configProps.put("connectionTimeout", connectionTimeout);
configProps.put("idleTimeout", idleTimeout);
configProps.put("dataSourceProperties", dsProps);
HikariConfig hc = new HikariConfig(configProps);
HikariDataSource ds = new HikariDataSource(hc);
return ds;
}
}
3. SecondayDataSourceConfig.java
#Configuration
public class SecondaryDataSourceConfig {
#Value("${secondary.spring.datasource.username}")
private String user;
#Value("${secondary.spring.datasource.password}")
private String password;
#Value("${secondary.spring.datasource.url}")
private String dataSourceUrl;
#Value("${spring.datasource.dataSourceClassName}")
private String dataSourceClassName;
#Value("${secondary.spring.datasource.poolName}")
private String poolName;
#Value("${secondary.spring.datasource.connectionTimeout}")
private int connectionTimeout;
#Value("${secondary.spring.datasource.maxLifetime}")
private int maxLifetime;
#Value("${secondary.spring.datasource.maximumPoolSize}")
private int maximumPoolSize;
#Value("${secondary.spring.datasource.minimumIdle}")
private int minimumIdle;
#Value("${secondary.spring.datasource.idleTimeout}")
private int idleTimeout;
#Bean(name="hikari_secondary")
public HikariDataSource getHikariDataSourceSecondary() {
Properties dsProps = new Properties();
dsProps.put("url", dataSourceUrl);
dsProps.put("user", user);
dsProps.put("password", password);
Properties configProps = new Properties();
configProps.put("dataSourceClassName", dataSourceClassName);
configProps.put("poolName", poolName);
configProps.put("maximumPoolSize", maximumPoolSize);
configProps.put("minimumIdle", minimumIdle);
configProps.put("minimumIdle", minimumIdle);
configProps.put("connectionTimeout", connectionTimeout);
configProps.put("idleTimeout", idleTimeout);
configProps.put("dataSourceProperties", dsProps);
HikariConfig hc = new HikariConfig(configProps);
HikariDataSource ds = new HikariDataSource(hc);
return ds;
}
}
4. Application.java
#SpringBootApplication
#ComponentScan("com.xxxx.springsql2o")
#EnableAutoConfiguration
public class Application
{
public static void main( String[] args )
{
SpringApplication.run(Application.class, args);
}
#Autowired
#Qualifier("hikari_primary")
DataSource hikariDataSourcePrimary;
#Autowired
#Qualifier("hikari_secondary")
DataSource hikariDataSourceSecondary;
#Bean(name= "primary_db")
public Sql2o getPrimarySql2o()
{
return new Sql2o(hikariDataSourcePrimary);
}
#Bean(name= "secondary_db")
public Sql2o getSecondarySql2o()
{
return new Sql2o(hikariDataSourceSecondary);
}
}
Spring boot is auto-configuring your application via #EnableAutoConfiguration (note that this annotation is already included in the composed #SpringBootApplication annotation). So my guess would be that you have some dependency that spring is trying to auto-configure (e.g. JPA) which uses/needs DataSource. If you can live with this, you can add #Primary to on of your DataSource Bean provider methods in order to satisfy that dependency.
So, for instance:
#Bean(name="hikari_primary")
#Primary
public HikariDataSource getHikariDataSourcePrimary() {...
Even if this should work, it would be recommended to remove auto-configuration for e.g. JPA or whatever spring boot is trying to auto-configure but you don't use/need and configure everything manually as it suits your application needs. Have two databases is certainly a custom configuration and does not conform to the spring boot easy-out-of-the-box approach.

How to use mockito for testing Database connection

I am using Junit to test my jersey api. I want to test DAO without a database. I tried using Mockito but still not able to use mock object to test the DAO which contains Hibernate calls to DB. I want to write Junit for my Helper class which calls the DAO.Can anyone provide a solution with some sample code to mock the DB Connections in DAO.
EDIT :
Status.java
#GET
#Produces(MediaType.TEXT_PLAIN)
public String getDBValue() throws SQLException {
DatabaseConnectionDAO dbConnectiondao = new DatabaseConnectionDAO();
String dbValue = dbConnectiondao.dbConnection();
return dbValue;
}
DatabaseConnectionDAO.java
private Connection con;
private Statement stmt;
private ResultSet rs;
private String username;
public String dbConnection() throws SQLException{
try{
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "root", "root");
stmt = con.createStatement();
rs =stmt.executeQuery("select * from test");
while(rs.next()){
username = rs.getString(1);
}
}catch(Exception e){
e.printStackTrace();
}finally{
con.close();
}
return username;
}
TestDatabase.java
#Test
public void testMockDB() throws SQLException{
DatabaseConnectionDAO mockdbDAO = mock(DatabaseConnectionDAO.class);
Connection con = mock(Connection.class);
Statement stmt = mock(Statement.class);
ResultSet rs = mock(ResultSet.class);
Client client = Client.create();
WebResource webResource = client.resource("myurl");
ClientResponse response = webResource.accept(MediaType.TEXT_PLAIN).get(ClientResponse.class);
verify(mockdbDAO).dbConnection();
//when(rs.next()).thenReturn(true);
when(rs.getString(1)).thenReturn(value);
actualResult = response.getEntity(String.class);
assertEquals(expectedResult,actualResult );
}
I think you may be missing the idea of how the DAO should be mocked. You shouldn't have to worry about any connections. Generally, you just want to mock what happens, when its methods are called, say a findXxx method. For instance, say you have this DAO interface
public interface CustomerDAO {
public Customer findCustomerById(long id);
}
You could mock it like
CustomerDAO customerDao = Mockito.mock(CustomerDAO.class);
Mockito.when(customerDao.findCustomerById(Mockito.anyLong()))
.thenReturn(new Customer(1, "stackoverflow"));
You would then have to "inject" that mocked instance into the class that depends on it. For example, if a resource class needs it, you could inject it via the constructor
#Path("/customers")
public class CustomerResource {
CustomerDAO customerDao;
public CustomerResource() {}
public CustomerResource(CustomerDAO customerDao) {
this.customerDao = customerDao;
}
#GET
#Path("/{id}")
#Produces(MediaType.APPLICATION_JSON)
public Response findCustomer(#PathParam("id") long id) {
Customer customer = customerDao.findCustomerById(id);
if (customer == null) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
return Response.ok(customer).build();
}
}
...
new CustomerResource(customerDao)
No when you hit the findCustomer method, the DAO will always return the Customer in the mocked DAO.
Here's a complete test, using the Jersey Test Framework
public class CustomerResourceTest extends JerseyTest {
private static final String RESOURCE_PKG = "jersey1.stackoverflow.standalone.resource";
public static class AppResourceConfig extends PackagesResourceConfig {
public AppResourceConfig() {
super(RESOURCE_PKG);
CustomerDAO customerDao = Mockito.mock(CustomerDAO.class);
Mockito.when(customerDao.findCustomerById(Mockito.anyLong()))
.thenReturn(new Customer(1, "stackoverflow"));
getSingletons().add(new CustomerResource(customerDao));
}
}
#Override
public WebAppDescriptor configure() {
return new WebAppDescriptor.Builder()
.initParam(WebComponent.RESOURCE_CONFIG_CLASS,
AppResourceConfig.class.getName()).build();
}
#Override
public TestContainerFactory getTestContainerFactory() {
return new GrizzlyWebTestContainerFactory();
}
#Test
public void testMockedDAO() {
WebResource resource = resource().path("customers").path("1");
String json = resource.get(String.class);
System.out.println(json);
}
}
The Customer class is simple a POJO with a long id, and String name. The dependency for The Jersey Test Framework is
<dependency>
<groupId>com.sun.jersey.jersey-test-framework</groupId>
<artifactId>jersey-test-framework-grizzly2</artifactId>
<version>1.19</version>
<scope>test</scope>
</dependency>
UPDATE
The above example uses Jersey 1, as I saw that the OP is using Jersey 1. For a complete example using Jersey 2 (with annotation injection), see this post
Short answer just don't !
The code that need to be unit tested is the client of the DAO, hence what need to be mocked are the DAOs. DAOs are the component that will integrate the app with an external system (here a database) so they have to be tested as integration tests (i.e. with a real database).

Junit Test unable to load Properties File

I'm trying to run a simple test to check values in a properties file which I've saved in the src/test/resources folder of my Maven project but the JUnit test is failing. My test is picking up the File OK but it doesn't return the expected value as the file doesn't look like its getting loaded. Anyone else have a similar issue? My code/test are as follows:
My Application Context File:
<bean id="myProps" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:test.properties"/>
</bean>
My Code:
#Resource(name = "myProps") private Properties myProps;
#Value("#{myProps['totalNumberOfChanges']}") private String totalNumberOfChangesStr;
#Value("#{myProps['delayTime']}") private String delayTimeStr;
public void parseAttributesFromConfigFile() {
String methodName = "parsePropertyAttributesFromConfigFile";
try {
totalNumberOfChanges = Integer.parseInt(totalNumberOfChangesStr);
delayTime = Integer.parseInt(delayTimeStr);
numEntriesToIterateThru = (totalNumberOfChanges / delayTime);
} catch (NumberFormatException nfe) {
LOGGER.error(methodName, "", "Number Format Exception Occured" + nfe.getMessage());
}
}
My Junit Test:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "classpath:META-INF/spring/Testpu.xml" })
public class ConfigPropertiesTest {
private final int NUM_ENTRIES_TO_ITERATE_THRU = 100;
private final int TOTAL_NUMBER_OF_CHANGES = 100000;
private final int DELAY_TIME = 1000;
private ConfigProperties configProperties;
#Before
public void setUp() throws Exception {
configProperties = new ConfigProperties();
}
#Test
public final void testParseAttributesFromConfigFileIsCalled() {
configProperties.parseAttributesFromConfigFile();
int numEntriesToIterateOver = configProperties.getNumEntriesToIterateThru();
assertEquals(numEntriesToIterateOver, NUM_ENTRIES_TO_ITERATE_THRU);
int numberOfChanges = configProperties.getTotalNumberOfChanges();
assertEquals(numberOfChanges, TOTAL_NUMBER_OF_CHANGES);
int delayTime = configProperties.getDelayTime();
assertEquals(delayTime, DELAY_TIME);
}
}
You are creating the ConfigProperties class in your Before method. If you want Spring to populated values based on annotations the bean must be created as part of the Spring context. If you have an instance of ConfigProperties in your Spring context, load that instance into your test using #Autowired