whilie calling getBean( with Impl class) then getting below exception? - spring-4

Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.dav.spring.domain.HelloWorldImpl] is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:319)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:985)
at Test.main(Test.java:24)
interface :
public interface HelloWorld {
void sayHello(String helloStr);}
impl class :
package com.dav.spring.domain;
public class HelloWorldImpl implements HelloWorld {
#Override
public void sayHello(String helloStr) {
System.out.println("Welcome to spring 4" + helloStr);
}
}
Configuraion Class:
#Configuration
public class MyConfiguration {
#Bean(name = "helloworld")
#Description("This is newly added in spring 4")
#Scope("prototype") // If removed this, it's fine.
HelloWorld getHelloWorldImpl() {
return new HelloWorldImpl();
}
}
Main class:
public class Test {
public static void main(String[] args) {
// We did configuration by using JavaConfiguration so
// we should use like this
AnnotationConfigApplicationContext antConf = new AnnotationConfigApplicationContext(
MyConfiguration.class);
HelloWorld byParentClass = antConf.getBean(HelloWorld.class);
byParentClass.sayHello(" Raju");
System.out.println(byParentClass.hashCode());
HelloWorld byBeanName = (HelloWorld) antConf.getBean("helloworld");
byBeanName.sayHello(" Chinna");
System.out.println(byBeanName.hashCode());
HelloWorldImpl byImplClass = antConf.getBean(HelloWorldImpl.class);
byImplClass.sayHello(" Daveedu Raju");
}
}

Related

Spring redis unable to autowire repository

I'm using custom crudrespository to persist data in redis. However, I'm unable to autowire custom repository.
All the configuration seems correct and redis is running on my local.
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface CustomRepository extends CrudRepository<String,
Long> {
String get(String key);
void put(String key, String value);
}
//////////
public class StorageServiceImpl implements IStorageService {
#Autowired
private CustomRepository respository;
#Override
public void saveParameter() {
this.respository.put("key1","value1");
}
#Override
public String getParameter() {
return this.respository.get("key1");
}
/////
#Service
public interface IStorageService {
void saveParameter();
String getParameter();
}
///////
#SpringBootApplication(scanBasePackages = {"com.example.cache"})
#EnableRedisRepositories(basePackages = {"com.example.cache.repository"})
public class ApplicationConfiguration {
public static void main(String[] args){
SpringApplication.run(ApplicationConfiguration.class, args);
new StorageServiceImpl().saveParameter();
System.out.println(new StorageServiceImpl().getParameter());
}
}
When I try running this application using gradle bootRun, I get
Exception in thread "main" java.lang.NullPointerException
at com.example.cache.impl.StorageServiceImpl.saveParameter(StorageServiceImpl.java:16)
at com.example.cache.ApplicationConfiguration.main(ApplicationConfiguration.java:17)
Not sure what's wrong?
You can't use new on any bean, you need to #Autowire it. The annotations only work with spring managed beans at every level.
Add a new bean with a a storage service and a method that makes your call after it is created.
Also, I can't remember if the spring-boot creates the bean if there is only one implementation but I believe your StorageServiceImpl needs the #Service annotation, not the interface.
Delete this from your ApplicationConfiguration class.
new StorageServiceImpl().saveParameter();
System.out.println(new StorageServiceImpl().getParameter());
Then add this new class.
#Service
public class Startup {
#Autowired
IStorageService storageService;
#PostConstruct
public void init(){
storageService.saveParameter();
System.out.println(storageService().getParameter());
}
}
And you need a config
#Configuration
#EnableRedisRepositories
public class ApplicationConfig {
#Bean
public RedisConnectionFactory connectionFactory() {
return new JedisConnectionFactory();
}
#Bean
public RedisTemplate<?, ?> redisTemplate() {
RedisTemplate<byte[], byte[]> template = new RedisTemplate<byte[], byte[]>();
return template;
}
}

PowerMokito 1.7.4 #Spy annotation is not working

I am using TestNg with PowerMocktion 1.7.4. #Spy is not working.
It's throwing below exception
org.mockito.exceptions.base.MockitoException: Cannot create a #Spy for
'service' field because the instance is missing
Example of correct usage of #Spy:
#Spy List mock = new LinkedList();
#PrepareForTest(StaticClass.class)
public class UsingPowerMockTest extends PowerMockTestCase {
#Spy
ServiceTest service;
#BeforeMethod
public void before() throws Exception {
//service = PowerMockito.spy(new ServiceTest());
mockStatic(StaticClass.class);
}
#Test
public void should_mock_static_method() {
PowerMockito.when(StaticClass.randomGenerator(Mockito.anyInt())).thenReturn("asd");
String randomString = service.getRandomString(20);
System.out.println(randomString);
}
}

Test Spring Mvc controller and inject static class

The following code is the standard method to write a JUnit test for a Mvc controller.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = ApplicationTestCassandra.class)
#WebAppConfiguration
public class TestControllerTests {
#Autowired
private WebApplicationContext webApplicationContext;
private MockMvc mockMvc;
#Before
public void setup() throws Exception {
this.mockMvc = webAppContextSetup(webApplicationContext).build();
}
#Test
public void testupTimeStart() throws Exception {
this.mockMvc.perform(get("/uptime"))
.andExpect(status().isOk());
}
}
This works fine, but I would like to replace an autowired class with a special class for testing. The class CassandraSimpleConnection is injected via #Autowired in my controller.
I have tried several approaches, but no luck.
The following code fails because of an Mvc 404 error, because I guess my application with the REST interface is not running at all.
#RunWith(SpringJUnit4ClassRunner.class)
//ApplicationTestCassandra is SpringBoot application startpoint class with #SpringBootApplication annotation
//#ContextConfiguration(classes = ApplicationTestCassandra.class, loader = AnnotationConfigContextLoader.class)
#ContextConfiguration(loader = AnnotationConfigWebContextLoader.class)//, classes = {ApplicationTestCassandra.class})
#WebAppConfiguration
public class TestControllerTests {
#Service
#EnableWebMvc
#ComponentScan(basePackages={"blabla.functionalTests"})
static class CassandraSimpleConnection {
public Metadata testConnection(TestConfiguration configuration) {
Metadata metadata = null;
// return metadata;
throw new RuntimeException("Could not connect to any server");
}
}
If I use
#ContextConfiguration(loader = AnnotationConfigWebContextLoader.class, classes = {ApplicationTestCassandra.class})
CassandraSimpleConnection is not replaced with my static class.
Could somebody help me please? The documentation about the annotations is quite confusing.
Read the comments and here is the solution:
#RunWith(SpringRunner.class)
#SpringBootTest(classes = { MyApplication.class })
public class MyTests {
#MockBean
private MyBeanClass myTestBean;
#Before
public void setup() {
...
when(myTestBean.doSomething()).thenReturn(someResult);
}
#Test
public void test() {
// MyBeanClass bean is replaced with myTestBean in the ApplicationContext here
}
}

RunWith SpringJUnit4ClassRunner gives error fail to load ApplicationContext with InitializingBean

I am using InitializingBean to initialise static properties in a modal class. This object I am auto wiring in a service
When I write a test case of service, I throws error: Failed to load ApplicationContext
Config class
public class AppConfig {
private String prop1;
protected void setProp1(String prop) {
this.prop1 = prop;
}
public String getProp1() {
return prop1;
}
}
PropertyIntilizer class
public class PropertyIntializer implements InitializingBean {
#Autowired
private AppConfig appConfig;
#Override
public void afterPropertiesSet() throws Exception {
appConfig.setProp1("PROP");
}
}
Service Class
#Service
public class Service {
#Autowired
private AppConfig appConfig;
public void doSomething(){
System.out.println(appConfig.getProp1());
}
}
TestClass
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = { TestConfig.class })
public class ServiceTest {
#Autowired
private Service service;
#Test
public void testService(){
service.doSomething();
}
}
This gives an error : Failed to load ApplicationContext
But when I remove Autowired AppConfig, it works
Edit:
TestConfig class
#Configuration
#ComponentScan(basePackages = { "base.package" })
public class TestConfig {
}
my main classes are in base.package.main and test classes in base.package.test
similar issue got resolved for me by adding JRE(thats comes with application server in my case websphere) in buid path

Apache Camel Integration test results in OutOfMemory

I have a simple Camel route that sends data to an external REST interface, integrated with Spring MVC.
#RestController
public class MyController {
#Autowired
private camelService camelService;
#RequestMapping(method = RequestMethod.POST, value = "/test")
#ResponseStatus(HttpStatus.CREATED)
public TestModel createEV(#Valid #RequestBody TestModel testModel) {
camelService.publishTestCase(testModel);
return testModel;
}
}
#Service
public class CamelService {
#Produce(uri = "direct:test")
private ProducerTemplate producerTemplate;
#Override
public void publishTestCase(TestModel testModel) {
producerTemplate.sendBody(testModel);
}
}
#Component
public class TestRouter extends SpringRouteBuilder
#Override
public void configure() throws Exception {
errorHandler(loggingErrorHandler(log).level(LoggingLevel.ERROR));
from("direct:test")
.routeId("testRoute")
.beanRef("mapper", "map")
.to("velocity:test.vm")
.setHeader(Exchange.HTTP_METHOD, simple("POST"))
.to("log:test?level=DEBUG&showAll=true&multiline=true&maxChars=100000")
.to("cxfrs:http://url.here");
}
}
Then there's an integration test for the rest endpoint with mockMvc that mocks the external camel endpoint.
#ContextConfiguration(loader = SpringApplicationContextLoader, classes = Application)
#WebIntegrationTest
#DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
class MyControllerIntegrationTest extends Specification {
#Autowired
private CamelContext camelContext
MockMvc mockMvc
#Autowired
WebApplicationContext wac
#Shared
def setupOnceRun = false
#Shared
def validInput = new File(JSON_DIR + '/valid.json').text
def setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build()
// no way to use setupSpec as Autowired fields can't be Shared
if (!setupOnceRun) {
ModelCamelContext mcc = camelContext.adapt(ModelCamelContext);
camelContext.getRouteDefinition("testRoute).adviceWith(mcc, new AdviceWithRouteBuilder() {
#Override
public void configure() throws Exception {
mockEndpointsAndSkip("cxfrs:http://url.here")
}
});
setupOnceRun = true
}
}
def 'valid scenario'() {
setup:
MockEndpoint mockEndpoint = (MockEndpoint) camelContext.hasEndpoint("mock:cxfrs:http://url.here")
mockEndpoint.expectedMessageCount(1)
when:
def response = mockMvc.perform(post('/test').content(validInput)).andReturn()
then:
response.getResponse().getStatus() == 201
mockEndpoint.assertIsSatisfied()
}
}
The test is passing if you run it by itself but once it's included in the build together with other integration tests it's constantly producing OutOfMemory. MaxPermSize is 4G, it doesn't look like that's an issue. I am new to Camel so my guess is that I am wiring the test in a wrong way. Would appreciate any suggestions.

Resources