Unit Testing Spring Services with actual Repository with in memory database - junit4

I am trying to test my #Service with the actual object of Spring Data Repository, where I am trying to use in memory database.I am using below annotation in my unit test.
#ActiveProfiles("test")
#RunWith(SpringRunner.class)
#EnableJpaRepositories
#SpringBootTest(classes = {MyService.class})
public class T24PortfolioRequestHandlerTest {
#Autowired
private MyService myService;
#Autowired
private MyRepository myRepository;
#Test
public void handleRequest() {
String output = myService.handleRequest(testData, "123", "TEST");
Assert.assertNotNull(output);
Assert.assertEquals("TESTING", output);
}
}
I am getting below exception while running the test.
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.....respository.MyRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
If I specify MyRepository.class in SpringBootConfiguratio(classes={MyService.class, MyRepository.class}) I am getting below error.
org.springframework.beans.BeanInstantiationException: Failed to instantiate [...respository.MyRepository]: Specified class is an interface
Is there any another way to tell spring boot about my repositories?

Related

Error in running spring boot application connected to mongodb

Once I run my code it gives below error. Howenter image description here I can solve it.
Field personRepository in com.example.demo.service.PersonService required a bean named 'mongoTemplate' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean named 'mongoTemplate' in your configuration.
You need to explicitly register bean to spring container.
#Configuration public class AppConfig {
public #Bean MongoClient mongoClient() {
return new MongoClient("localhost"); }
public #Bean MongoTemplate mongoTemplate() {
return new MongoTemplate(mongoClient(), "mydatabase");
} }

ApplicationContext Exception in Test with #WebMvcTest

I Have an Spring Boot Application (1.5.10.RELEASE) which contains a main (SpringBootApplication) like this:
#SpringBootApplication
#Configuration
#EntityScan(basePackages = { "db.modell", "db.modell.base" })
#ComponentScan(basePackages = { "de.gui.test" })
public class SpringBootConsoleApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(SpringBootConsoleApplication.class, args);
}
}
and two REST controllers like the following:
#RestController
#RequestMapping("/as")
public class AController {
#Autowired
private ARepository aRepository;
#RequestMapping(method = RequestMethod.GET)
public ResponseEntity<Collection<A>> getAs() {
return new ResponseEntity<>(orgtFarbeRepository.findAll(), HttpStatus.OK);
}
#RequestMapping(value = "/{id}", method = RequestMethod.GET)
public ResponseEntity<A> getA(#PathVariable long id) {
A a = ARepository.findOne(id);
if (party != null) {
return new ResponseEntity<>(ARepository.findOne(id), HttpStatus.OK);
} else {
return new ResponseEntity<>(null, HttpStatus.NOT_FOUND);
}
}
}
Furthermore I have a single test like this:
#RunWith(SpringRunner.class)
#WebMvcTest(AController.class)
public class AControllerTest {
#Autowired
private MockMvc mvc;
#MockBean
private ARepository ARepository;
#Test
public void firstTest() throws Exception {
A a = new aFarbe();
a.set....
when(ARepository.findAll()).thenReturn(Collections.singleton(a));
mvc.perform(
get("/as")
.accept(MediaType.APPLICATION_JSON_UTF8_VALUE)
)
.andExpect(status().isOk());
}
}
The repositories look like this:
public interface ARepository extends CrudRepository<A, Long>
{
Collection<A> findAll();
}
public interface BRepository extends CrudRepository<B, Long>
{
Collection<B> findAll();
}
A and B them self are JPA annotated classes. The whole application contains access to a database..
Furthermore I have a Service like this:
#Service
public class XService {
private static final Logger LOGGER = LoggerFactory.getLogger(XService.class);
#Autowired
private ARepository aRepository;
#Autowired
private BRepository bRepository;
...
}
The XService is not used via #Autowire or so (Just need to remove that):
So I try to run the AControllerTest I get the following error:
java.lang.IllegalStateException: Failed to load ApplicationContext at
org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
.. .. at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
Caused by:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'XService': Unsatisfied dependency
expressed through field 'BRepository'; nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type 'BRepository' available: expected at least 1
bean which qualifies as autowire candidate. Dependency annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true)}
.. .. at
org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:120)
at
org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
at
org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
... 26 more Caused by:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type 'BRepository' available: expected at least 1
bean which qualifies as autowire candidate. Dependency annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true)}
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1493)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 44 more
My assumption is that during the test more context is started than it should. The question is how can I prevent that? Which means only to start the context for the AControler and nothing more? I thought that based on the #WebMvcTest(AController.class) it should be limited already which looks like that it was not the case...
The referenced answer does not really answered my question but a in the context a hint gave me the solution. This means in consequence to add the following to my test:
so I have to add #OverrideAutoConfiguration(enabled=true):
#RunWith(SpringRunner.class)
#WebMvcTest(OrgtFarbenController.class)
#OverrideAutoConfiguration(enabled=true)
public class AControllerTest {
...
}

UnsatisfiedDependencyException in SpringMVC and MongoDB project

I'm working on a Spring MVC and MongoDB backed application.
My api is working fine,but i would like to create an integration test with Fongo in order to test saving a file and after getting this file by my services.
I have already tried, but when i added #Autowired in my Service class, it returned an UnsatisfiedDependencyException. My test fixture class is the following:
#ActiveProfiles({"test"})
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(
locations = {
"classpath*:config/servlet-config.xml",
"classpath*:config/SpringConfig.xml"})
#WebAppConfiguration
public class IntegrationTest {
#Autowired // returns UnsatisfiedDependencyException
private FileService fileService;
#Before
#Test
public void setUp() throws IOException {
Fongo fongo = new Fongo("dbTest");
DB db = fongo.getDB("myDb");
}
#Test
public void testInsertAndGetFile() throws IOException{
//create a file document in order to save
File file = new File();
file.setId("1");
file.setFileName("test1");
file.setVersionId("1");
//save the file
String id = fileService.storeFile(file);
//get the file
File fileDocument= fileService.getFileById("1");
//check if id is the file id which is expected
assertEquals(fileDocument.getId(), "1");
}
}
and i am receiving this log message:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.ots.openonefilesystem.integration.IntegrationTest': Unsatisfied dependency expressed through field 'fileService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean found for dependency [com.myproject.service.FileService]: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean found for dependency [com.myproject.service.FileService]: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
I'm using xml configuration.
How can i solve my testing error? In my service class FileService i have put #Service, however it seems that Spring expected at least 1 bean which qualifies as autowire candidate.
Also if i remove the #Autowired, the log returns NullpointerException when saving of getting the file,as it was expected.
PS: I use springFramework 4.3.3.RELEASE, spring-data-mongodb 1.9.5.RELEASE
Thank you in advance!
I had to configure Mock Database (Fongo), in order to #Autowired FileService. This, I made it via #ContextConfiguration(classes = {MockDatasourceConfig.class})
So, the correct test fixture class is the following:
#ActiveProfiles({"test"})
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = {MockDatasourceConfig.class})
#WebAppConfiguration
public class IntegrationTest{
#Autowired
private FileService fileService;
#Test
public void testInsertAndGetFile() throws IOException{
//create a file document in order to save
File file = new File();
file.setId("1");
file.setFileName("test1");
file.setVersionId("1");
//save the file and return his id
String id = fileService.storeFileGeneral(file);
//get the file
FileDocument fileDocument= fileService.getFileById(id);
//check that the file isn't null
assertNotNull(fileDocument);
//check if id is the file id which is expected
assertEquals(fileDocument.getId(), id);
assertEquals(fileDocument.getFileName(), "test1");
}
}
and the MockDatasourceConfig class is the following:
#Profile({"test"})
#Configuration
#PropertySource("classpath:mongo.properties")
#ComponentScan(basePackageClasses = {File.class})
#EnableMongoRepositories(basePackageClasses = RepositoryPackageMarker.class)
public class MockDatasourceConfig extends AbstractMongoConfiguration {
#Autowired
Environment env;
#Override
protected String getDatabaseName() {
return env.getProperty("mongo.dbname", "myDb");
}
#Override
public Mongo mongo() throws Exception {
return new Fongo(getDatabaseName()).getMongo();
}
#Bean
public GridFsTemplate gridFsTemplate() throws Exception {
return new GridFsTemplate( mongoDbFactory(),mappingMongoConverter());
}
}
P.S: With helpful advice of #M.Deinum

Configuration of chained transaction manager in SDN4 after migration from SDN3

At the moment I am trying to migrate from SDN3 to SDN4. In my project I use two databases: Neo4j and MySQL, so I end up with chained transaction manager. However, after migration I have problem with its configuration. Before the migration I had this:
#Bean(name = "transactionManager")
#Autowired
public PlatformTransactionManager neo4jTransactionManager(
LocalContainerEntityManagerFactoryBean entityManagerFactory, GraphDatabaseService graphDatabaseService)
throws Exception {
JtaTransactionManager neoTransactionManager = new JtaTransactionManagerFactoryBean(graphDatabaseService)
.getObject();
neoTransactionManager.setRollbackOnCommitFailure(true);
neoTransactionManager.setAllowCustomIsolationLevels(true);
JpaTransactionManager mysqlTransactioNmanager = new JpaTransactionManager(entityManagerFactory.getObject());
return new ChainedTransactionManager(mysqlTransactioNmanager, neoTransactionManager);
}
Now I have something like this:
#Bean(name = "transactionManager")
#Autowired
public PlatformTransactionManager neo4jTransactionManager(
LocalContainerEntityManagerFactoryBean entityManagerFactory, Neo4jTransactionManager neo4jTransactionManager)
throws Exception {
Neo4jTransactionManager neoTransactionManager = neo4jTransactionManager;
JpaTransactionManager mysqlTransactioNmanager = new JpaTransactionManager(entityManagerFactory.getObject());
return new ChainedTransactionManager(mysqlTransactioNmanager, neoTransactionManager);
}
However, project could not be deployed on server, because of this exception:
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire method: public org.springframework.transaction.PlatformTransactionManager com.project.config.ApplicationConfig.neo4jTransactionManager(org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean,org.springframework.data.neo4j.transaction.Neo4jTransactionManager) throws java.lang.Exception; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.data.neo4j.transaction.Neo4jTransactionManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
When mentioned part of configuration is commented project is properly deployed, but obviously there is an exception concerning missing transaction during save to MySQL database.
How should I configure this chained transaction manager in SDN4? It is hard to find any examples now, because SDN4 is quite recent and I really need to have Neo4j in standalone mode, so migration seems to be a good idea.
With this configuration I managed to successfully deploy my application:
#Bean(name = "transactionManager")
#Autowired
public PlatformTransactionManager neo4jTransactionManager(
LocalContainerEntityManagerFactoryBean entityManagerFactory,
Session session) throws Exception {
Neo4jTransactionManager neoTransactionManager = new Neo4jTransactionManager(session);
JpaTransactionManager mysqlTransactioNmanager = new JpaTransactionManager(entityManagerFactory.getObject());
return new ChainedTransactionManager(mysqlTransactioNmanager,neoTransactionManager);
}
I had also to add this element to my config:
#Override
#Bean
#Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public Session getSession() throws Exception {
return super.getSession();
}

spring batch jobexplorer issue

We are trying to run a spring batch which is failing with below issue.
My configs :
1) Spring boot
#ComponentScan(basePackages = { "some pkgs” })
#ImportResource("classpath:dataSource.xml")
#EnableAutoConfiguration(exclude = DataSourceTransactionManager.class)
public class CollateralReportGeneratorBootstrapper {
public static void main(String[] args) {
System.exit(SpringApplication.exit(SpringApplication.run(CollateralReportGeneratorBootstrapper.class, args)));
}
}
2) Batch
#Configuration
#EnableBatchProcessing
#ComponentScan(basePackages = { "some pkgs”})
public class ReportGenerator {
#Autowired
private JobBuilderFactory jobBuilderFactory;
#Autowired
private StepBuilderFactory stepBuilderFactory;
3) Dependencies : spring-batch-core, spring-batch-infrastructure, spring-boot-starter-batch
Please let me know if someone faced this issue or any idea about possible solutions !!
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'jobLauncherCommandLineRunner' defined in class path resource [org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.class]: Unsatisfied dependency expressed through constructor argument with index 1 of type [org.springframework.batch.core.explore.JobExplorer]: : No qualifying bean of type [org.springframework.batch.core.explore.JobExplorer] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.batch.core.explore.JobExplorer] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:747)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:462)
I would suggest start with following sample and add your launcher class to it...
http://spring.io/guides/gs/batch-processing/