today I'm having problem with spring.
Here is my code:
SpringConfig.java
package com.berrigan.addonsserver.springconfig;
import com.berrigan.addonsserver.EndPoint;
import org.glassfish.tyrus.server.Server;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
#Configuration
#ComponentScan(basePackages={"com.berrigan.addonsserver","com.berrigan.addonsserver.modules"})
public class SpringConfig {
#Bean
public Server server(EndPoint end){
return new Server("localhost",8025, "/margonem",null,end.getClass());
}
}
EndPoint.java
package com.berrigan.addonsserver;
import com.berrigan.addonsserver.modules.ResponseGenerator;
import com.berrigan.addonsserver.util.JSONOutputTemplate;
import com.google.gson.Gson;
import javax.websocket.OnMessage;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
#Component("endPoint")
#ServerEndpoint(value="/server")
public class EndPoint {
#Autowired
public ResponseGenerator rg;
public EndPoint(){ System.out.println("Sucks");}
public EndPoint(ResponseGenerator rg){ this.rg = rg; System.out.println("Rg is set");}
#OnMessage
public String onMessage(String message, Session s){
Gson g = new Gson();
if(rg == null) System.out.println("DI DOESN'T WORK");
else{
JSONOutputTemplate output = rg.generateResponse(null);//new JSONOutputTemplate();//
g.toJson(output);
}
return message;
}
public void setResponseGenerator(ResponseGenerator rg){
System.out.println("This works");
this.rg = rg;
}
}
ResponseGenerator.java
package com.berrigan.addonsserver.modules;
import com.berrigan.addonsserver.annotations.AuthorizationRequired;
import com.berrigan.addonsserver.util.JSONInputTemplate;
import com.berrigan.addonsserver.util.JSONOutputTemplate;
import org.springframework.stereotype.Component;
#Component
public class ResponseGeneratorImpl implements ResponseGenerator{
#Override
#AuthorizationRequired
public JSONOutputTemplate generateResponse(JSONInputTemplate data) {
return new JSONOutputTemplate();
}
}
My output says "Sucks", and "DI DOESN'T WORK". When I tried to get ResponseGenerator bean from ApplicationConfig, there wasn't null. I've no idea what's wrong. Thanks in advance.
Related
I have a method that evicts all the caches. PFB code for same:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service;
import com.admin.AdminResponse;
#Service
public class CachingService {
private final static Logger logger = LoggerFactory.getLogger(CachingService.class);
#Autowired
protected CacheManager cacheManager;
public AdminResponse evictAllCaches() {
logger.info("Start - Clearing of cache");
cacheManager.getCacheNames().parallelStream()
.forEach(cacheName -> cacheManager.getCache(cacheName).clear());
AdminResponse adminResponse = new AdminResponse();
adminResponse.setMessage("ok");
logger.info("End - Clearing of cache");
return adminResponse;
}
}
Below is the unit test I'm trying to write:
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import com.admin.AdminResponse;
#ExtendWith(SpringExtension.class)
public class CachingServiceTest {
#InjectMocks
private CachingService testCachingService;
#Mock
protected CacheManager cacheManager;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
#Test
public void testEvictAllCaches() {
AdminResponse adminResponse = testCachingService.evictAllCaches();
assertEquals("ok", adminResponse.getMessage());
}
}
I'm unable to understand how to write unit tests for code
cacheManager.getCacheNames().parallelStream()
.forEach(cacheName -> cacheManager.getCache(cacheName).clear());
Can someone please help? Thank you for your time!
You can write test code for Cache as follow:
#Test
public void testEvictAllCaches() {
Cache cache = Mockito.mock(Cache.class);
when(cacheManager.getCacheNames()).thenReturn(List.of("cacheName1", "cacheName2"));
Mockito.when(cacheManager.getCache(anyString())).thenReturn(cache);
AdminResponse adminResponse = testCachingService.evictAllCaches();
assertEquals("ok", adminResponse.getMessage());
}
I'm using redis in my springboot rest application to store cache. But the problem I'm facing is once it is stored in redis my api only hits the redis not the database. I've added time out property it didn't work. I've tried CacheManager to get the cache and call CacheEvict to clear the cache and then CachePut to put the data again, but it didn't work. These are the things I've tried so far. I wanted my redis cache to refresh after a given time set by me. Any advice on this? Here is my code below:
package com.dg.repo;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import com.dg.entity.FlightEntity;
public interface FlightRepo extends JpaRepository<FlightEntity, String> {
#Query(value="select distinct txtFlightName\r\n"
+ "from {test-schema}flights", nativeQuery = true)
List<String> getAllFlights();
#Query(value="select distinct txtFlightName from {test-schema}flights \r\n"
+ "where txtFlightName LIKE %:flightname%",nativeQuery = true)
List<String> getListofFlights(#Param("flightname")String flightname);
#Query(value="select distinct txtBookingCode,txtFlightName from {test-schema}flights \r\n"
+ "where txtFlightName LIKE %:flightname%",nativeQuery = true)
List<FlightEntity> getFlightEntity(#Param("flightname")String flightname);
}
package com.dg.repo;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery;
import com.dg.entity.FlightEntity;
public abstract class FlightRepoImpl implements FlightRepo {
RedisTemplate template;
HashOperations hashOperations;
public FlightRepoImpl(RedisTemplate template, HashOperations hashOperations) {
super();
this.template = template;
this.hashOperations = template.opsForHash();
}
#Override
public List<String> getAllFlights() {
return hashOperations.values("FlightModel");
}
#Override
public List<String> getListofFlights(String flightname) {
return (List<String>) hashOperations.get("FlightModel", flightname);
}
}
package com.dg.service;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import com.dg.model.FlightModel;
import com.dg.repo.FlightRepo;
public class FlightService {
#Autowired
FlightRepo flightRepo;
#Autowired
ModelMapper modelMapper;
#Scheduled(fixedRate = 50000)
#Caching(evict = {#CacheEvict(value="getFlightList", key="#flightname")})
public FlightModel getFlightByFlightName(String flightName)
{
package com.dg.model;
import java.io.Serializable;
import java.util.List;
public class FlightModel implements Serializable{
private List<Object> listofflightname;
public List<Object> getListofflightname() {
return listofflightname;
}
public void setListofflightname(List<Object> listofflightname) {
this.listofflightname = listofflightname;
}
}
package com.dg.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
#Entity
public class FlightEntity {
#Id
#Column(name="txtBookingCode")
private String bookingCode;
#Column(name="txtFlightName")
private String flightname;
public String getBookingCode() {
return bookingCode;
}
public void setBookingCode(String bookingCode) {
this.bookingCode = bookingCode;
}
public String getFlightname() {
return flightname;
}
public void setFlightname(String flightname) {
this.flightname = flightname;
}
}
package com.dg.config;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
import redis.clients.jedis.JedisPoolConfig;
#Configuration
#EnableRedisRepositories
#Profile("test")
public class RedisConfig {
#Value("${spring.redis.cluster.nodes}")
private String nodesProperty;
#Bean
public JedisConnectionFactory jedisConnectionFactory()
{
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMinIdle(2);
poolConfig.setMaxIdle(5);
poolConfig.setMaxTotal(20);
poolConfig.setEvictorShutdownTimeoutMillis(10000);
String [] nodesArray=nodesProperty.split(",");
List<String> nodes = new ArrayList<String>(Arrays.asList(nodesArray));
RedisClusterConfiguration configuration=new RedisClusterConfiguration(nodes);
configuration.setMaxRedirects(100);
JedisConnectionFactory connectionFactory = new JedisConnectionFactory(configuration);
connectionFactory.setPoolConfig(poolConfig);
return connectionFactory;
}
#Bean
public RedisTemplate redisTemplate()
{
RedisTemplate template = new RedisTemplate();
template.setConnectionFactory(jedisConnectionFactory());
return template;
}
}
package com.dg;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
#SpringBootApplication
#EnableCaching
public class RedisTestApplication {
public static void main(String[] args) {
SpringApplication.run(RedisTestApplication.class, args);
}
}
I have an application based on Jersey JAX-RS. I need to refactor the event handler and therefore also write a test for it.
I'm trying to do this with the JerseyTest Framework. I created a configuration to extend ResourceConfig, but when I use the target () call the handler is not called.
I will present the situation using code.
Here is an example Resource class:
package com.my.page;
import org.glassfish.hk2.api.messaging.Topic;
import com.my.core.entity.Link;
import com.my.core.location.LinkHitLocationFactory;
import com.my.core.service.LinkService;
import com.my.core.service.link.LinkFinder;
import com.my.core.service.link.LinkFinderFactory;
import com.my.event.LinkHitEvent;
import com.my.exception.FragmentNotFoundException;
import javax.annotation.security.PermitAll;
import javax.inject.Inject;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
#PermitAll
#Path("/")
public class LinkResource {
#Inject
private LinkService linkService;
#Inject
private Topic<LinkHitEvent> linkHitPublisher;
#Inject
private LinkFinderFactory linkFinderFactory;
#Inject
private LinkHitLocationFactory linkHitLocationFactory;
#GET
#Path("/{fragment:[^ ]{1,32}}")
public Response redirect(
#PathParam("fragment") String fragment,
#HeaderParam("Range") String range,
#HeaderParam("User-Agent") String userAgent,
#Context HttpHeaders headers) throws Exception {
LinkFinder linkFinder = linkFinderFactory.getLinkFinder(fragment);
Link link = linkFinder.getLink(fragment);
if (link.isExpired()) {
throw new FragmentNotFoundException(fragment);
}
linkService.insertHit();
linkHitPublisher.publish(new LinkHitEvent(link));
return handlerFactory.getHandler(link).handleGet(link, range).build();
}
}
Event test:
package com.my.page;
import org.glassfish.hk2.extras.events.internal.TopicDistributionModule;
import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import pl.comvision.hk2.events.ThreadedEventDistributorService;
import com.my.client.CallbackTargetBuilder;
import com.my.core.entity.Link;
import com.my.core.mapper.LinkMapper;
import com.my.core.service.LinkService;
import com.my.page.resource.LinkResource;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Response;
import static javax.ws.rs.core.Response.Status.TEMPORARY_REDIRECT;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*;
#RunWith(MockitoJUnitRunner.class)
public class CallbackEventTest extends JerseyTest {
#Mock
private LinkMapper linkMapper;
#Mock
private LinkService linkService;
private CallbackTargetBuilder callbackTargetBuilder;
private final String callbackUrl = "";
#Override
protected Application configure() {
this.callbackTargetBuilder = spy(new CallbackTargetBuilder(this.callbackUrl));
ResourceConfig config = new ResourceConfig(LinkResource.class);
config.register(new TopicDistributionModule());
config.register(new AbstractBinder() {
#Override
protected void configure() {
addActiveDescriptor(ThreadedEventDistributorService.class).setRanking(100);
}
});
config.register(new EventsContainerListener(CallbackEventHandler.class));
config.register(new AbstractBinder() {
#Override
protected void configure() {
bind(linkMapper).to(LinkMapper.class);
bind(linkService).to(LinkService.class);
bind(mock(LinkService.class)).to(LinkService.class);
bind("").to(String.class).named("varPath");
bind("127.0.0.1").to(String.class).named("requestIP");
bind(callbackTargetBuilder).to(CallbackTargetBuilder.class);
}
});
return config;
}
#Test
public void publish_event() {
Link link = mock(Link.class);
when(link.getUrl()).thenReturn("example");
when(link.getName()).thenReturn("test");
when(linkMapper.getByName(anyString())).thenReturn(link);
Response response = target("/testY").property("jersey.config.client.followRedirects", false).request().get();
assertEquals(TEMPORARY_REDIRECT.getStatusCode(), response.getStatus());
verify(callbackTargetBuilder).build();
}
}
For testing purposes, I only injected callbackTargetBuilder into the handler, and called the build method on it to verify the call:
package com.my.page;
import org.glassfish.hk2.api.messaging.MessageReceiver;
import org.glassfish.hk2.api.messaging.SubscribeTo;
import org.jvnet.hk2.annotations.Service;
import com.my.client.CallbackTargetBuilder;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.MediaType;
#Service
#Singleton
#MessageReceiver
public class CallbackEventHandler {
#Named("callbackUrl")
private String url;
#Inject
private CallbackTargetBuilder callbackTargetBuilder;
#MessageReceiver
public void handle(#SubscribeTo LinkHitEvent event) {
Form form = new Form();
form.param("id", event.getLink().getId().toString());
form.param("name", event.getLink().getName());
callbackTargetBuilder.build();
Client client = ClientBuilder.newClient();
client.target(url).request().post(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
}
}
Edit:
I tried to register dependencies differently, but it does not bring satisfactory results. Each time verification fails:
verify (callbackTargetBuilder) .build ();
Looking for information I found that I can configure the DeploymentContext, but I don't know if this is the right direction.
Edit the second:
A quick test shows that I may have some more basic problem with mocking. Because the call:
verify (linkService) .insertHit (anyObject ());
It also fails.
I will write only for posterity that the above code is correct. The problem was a lot of small bugs in the tested code and how to mock it.
I'm trying to persist a cassandra entity but on startup I get:
Caused by: org.springframework.data.mapping.MappingException: Couldn't find PersistentEntity for type class com.service.model.Cart!
This is my entity class:
package com.service.model;
import io.vavr.collection.LinkedHashMap;
import io.vavr.collection.Map;
import lombok.Getter;
import lombok.ToString;
import org.springframework.data.cassandra.core.mapping.PrimaryKey;
import org.springframework.data.cassandra.core.mapping.Table;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import java.util.function.Function;
#ToString
#Table("carts")
public class Cart {
#Getter
#PrimaryKey
private final UUID uuid;
private final Map<CartItemKey, CartItem> items;
public Cart(UUID uuid) {
this(uuid, LinkedHashMap.empty());
}
private Cart(UUID uuid, Map<CartItemKey, CartItem> items) {
this.uuid = Objects.requireNonNull(uuid, "Cart's uuid cannot be null");
this.items = Objects.requireNonNull(items, "Cart's items cannot be null");
}
}
This is my CassandraConfig:
package com.service.configuration;
import com.service.model.Cart;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.cassandra.config.AbstractClusterConfiguration;
import org.springframework.data.cassandra.core.convert.CassandraCustomConversions;
import org.springframework.data.cassandra.core.cql.keyspace.CreateKeyspaceSpecification;
import org.springframework.data.cassandra.core.cql.keyspace.KeyspaceOption;
import org.springframework.util.StringUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import static java.util.Collections.singletonList;
#Configuration
public class CassandraConfig extends AbstractClusterConfiguration {
#Value("${spring.data.cassandra.keyspace-name}")
private String keyspaceName;
#Value("${spring.data.cassandra.contact-points}")
private String contactPoints;
#Override
protected List<CreateKeyspaceSpecification> getKeyspaceCreations() {
return singletonList(
CreateKeyspaceSpecification.createKeyspace(keyspaceName)
.ifNotExists()
.with(KeyspaceOption.DURABLE_WRITES, true)
.withSimpleReplication());
}
#Override
protected boolean getMetricsEnabled() {
return false;
}
#Override
protected String getContactPoints() {
return contactPoints;
}
#Bean
public CassandraCustomConversions customConversions() {
List<Converter<?, ?>> converters = new ArrayList<>();
converters.add(new CartWriteConverter());
converters.add(new CartReadConverter());
return new CassandraCustomConversions(converters);
}
static class CartWriteConverter implements Converter<Cart, String> {
public String convert(Cart source) {
try {
return new ObjectMapper().writeValueAsString(source);
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
}
static class CartReadConverter implements Converter<String, Cart> {
public Cart convert(String source) {
if (StringUtils.hasText(source)) {
try {
return new ObjectMapper().readValue(source, Cart.class);
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
return null;
}
}
}
And lastly my Application:
package com.service.cart;
import org.axonframework.springboot.autoconfig.AxonServerAutoConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.data.cassandra.repository.config.EnableCassandraRepositories;
import org.springframework.scheduling.annotation.EnableAsync;
#EnableCaching
#EnableAsync
#EnableFeignClients
#SpringBootApplication
#EnableAutoConfiguration(exclude = {
DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
HibernateJpaAutoConfiguration.class,
AxonServerAutoConfiguration.class})
#EnableCassandraRepositories(basePackages = "com.service.repository")
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
What seems puzzling to me is that when I remove customConversions() bean it fails with a different error - not being able to map vavr Map, so spring must have scanned and registered this entity so that it got inspected. This is expected while it is not cassandra data type but in my understanding adding my custom conversions should solve this problem.
I also tried experimenting with #EntityScan with the same results.
Any help would be appreciated.
I'm trying to put together an SDK that uses Spring internally through a context it manages of its own. I want the jar that gets built to be usable regardless of whether or not Spring is in use on the application that wants to use the SDK.
I have something that works when it is running on its own. However if I attempt to use the SDK inside another Spring context (in my case a Spring Boot based application) I get a org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type exception.
Try as I might I cannot understand how to get this working, or indeed what I am doing wrong. The classes below show what I'm doing, the org.example.testapp.MySDKTest fails with the exception while the org.example.test.MySDKTest successfully passes. Sorry there is so much code but I can't reproduce the issue with a simplified case.
SDK source
package org.example.mysdk;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.example.mysdk.MyService;
import org.example.mysdk.MyServiceConfiguration;
public final class MySDK {
private static ApplicationContext applicationContext;
public static <T extends MyService> T getService(Class<? extends MyService> clazz, MyServiceConfiguration configuration) {
T tmp = (T) getApplicationContext().getBean(clazz);
tmp.setConfiguration(configuration);
return tmp;
}
private static ApplicationContext getApplicationContext() {
if (applicationContext == null) {
applicationContext = new AnnotationConfigApplicationContext(SpringContext.class);
}
return applicationContext;
}
}
.
package org.example.mysdk;
import org.springframework.beans.factory.annotation.Autowired;
public abstract class MyService {
private MyServiceConfiguration configuration;
#Autowired
private MyAutowiredService myAutowiredService;
MyService() {
}
MyService(MyServiceConfiguration configuration) {
super();
this.configuration = configuration;
}
public MyServiceConfiguration getConfiguration() {
return configuration;
}
void setConfiguration(MyServiceConfiguration configuration) {
this.configuration = configuration;
}
String getSomething(String in) {
return "something + " + myAutowiredService.getThing(configuration.getValue()) + " and " + in;
}
}
.
package org.example.mysdk;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
#Service
#Scope("prototype")
public class MyServiceImpl1 extends MyService {
public MyServiceImpl1() {
}
public MyServiceImpl1(MyServiceConfiguration configuration) {
super(configuration);
}
public String method1() {
return this.getSomething("method1");
}
}
.
package org.example.mysdk;
public class MyServiceConfiguration {
private String value;
public void setValue(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
.
package org.example.mysdk;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
#Service
public class MyAutowiredService {
private String thing = "a value";
public String getThing(String in) {
return thing + " " + in;
}
#PostConstruct
void init() {
System.out.println("MyAutowiredService bean created");
}
}
.
package org.example.mysdk;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
#Configuration
#ComponentScan(basePackages = {
"org.example.mysdk"
})
public class SpringContext {
}
Tests
This first test fails with a org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type exception,
package org.example.testapp;
import static org.junit.Assert.*;
import org.example.mysdk.MyServiceConfiguration;
import org.example.mysdk.MyServiceImpl1;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = App.class, loader = AnnotationConfigContextLoader.class)
public class MySDKTest {
#Autowired
MyServiceImpl1 service;
#Test
public void test() {
MyServiceConfiguration conf = service.getConfiguration();
assertEquals(conf.getValue(), "this is the instance configuration");
}
}
.
package org.example.testapp;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.example.mysdk.MySDK;
import org.example.mysdk.MyServiceConfiguration;
import org.example.mysdk.MyServiceImpl1;
#Configuration
#ComponentScan(basePackages = {
"org.example.testapp"
})
public class App {
#Bean
public MyServiceImpl1 myServiceImpl1() {
MyServiceConfiguration configuration = new MyServiceConfiguration();
configuration.setValue("this is the instance configuration");
return MySDK.getService(MyServiceImpl1.class, configuration);
}
}
and this test succeeds,
package org.example.test;
import static org.junit.Assert.*;
import org.example.mysdk.MySDK;
import org.example.mysdk.MyServiceConfiguration;
import org.example.mysdk.MyServiceImpl1;
import org.junit.Test;
public class MySDKTest {
#Test
public void test() {
MyServiceConfiguration configuration = new MyServiceConfiguration();
configuration.setValue("this is the instance configuration");
MyServiceImpl1 service = MySDK.getService(MyServiceImpl1.class, configuration);
assertEquals(service.getConfiguration().getValue(), "this is the instance configuration");
}
}
If I've gone about this the completely wrong way I'm happy to hear suggestions of how this should be done differently!
You have to modify two files.
First App.java, it should scan for "org.example.mysdk" package to inject myAutowiredService in abstract class MyService, If not it has to be created in App.java. And the name of the MyServiceImpl1 bean must be different from myServiceImpl1 as it will conflict.
package org.example.testapp;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.example.mysdk.MySDK;
import org.example.mysdk.MyServiceConfiguration;
import org.example.mysdk.MyServiceImpl1;
#Configuration
#ComponentScan(basePackages = {
"org.example.testapp", "org.example.mysdk"
})
public class App {
#Bean
public MyServiceImpl1 myServiceImpl() {
MyServiceConfiguration configuration = new MyServiceConfiguration();
configuration.setValue("this is the instance configuration");
return MySDK.getService(MyServiceImpl1.class, configuration);
}
}
Then secondly in MySDKTest.java should inject myServiceImpl which was created in App.java
import static org.junit.Assert.*;
import org.example.mysdk.MyServiceConfiguration;
import org.example.mysdk.MyServiceImpl1;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = App.class, loader = AnnotationConfigContextLoader.class)
public class MySDKTest {
#Autowired
MyServiceImpl1 myServiceImpl;
#Test
public void createOxiAccountService() {
MyServiceConfiguration conf = myServiceImpl.getConfiguration();
assertEquals(conf.getValue(), "this is the instance configuration");
}
}