OSGI services not loading in Mockito unit tests - mockito

I have several service classes that are not loading in Mockito for unit testing. The services are being loaded in classes and Sling models using the #Reference and #Inject annotations.
The case is that I have several services and Sling models that are loading other services using the #Inject or #Reference annotations.
public class MyModel{
#Inject
SomeService service;
}
public class MyService{
#Reference
SomeOtherService service;
}
Then when I have a unit test mock the service, the injected services are not loaded. How do I get them loaded into the mock context so that they load are tested as well?

I found that I need to create an instance of the SomeService object and then use the AemContext.registerInjectActivateService() method or the SlingContext.registerInjectActivateService() method to inject them into the context so they are available when the classes being tested load.

You can simply use the mockito #InjectMocks annotation on your class under test and provide the services to be injected as #Mock.

Related

Micronaut and PowerMock

I am trying to use PowerMock(as i have some legacy static methods) in a micronaut based application. But when I try to run the application all micronaut beans are getting injected as null (and the underlying mocks as well)
#RunWith(PowerMockRunner.class)
#PrepareForTest({MyStaticClass.class, ClassToBeTested.class})
public class TestClass {
#InjectMocks
private ClassToBeTested obj1;
#Mock
private LegacyStaticClass1 obj2;
#Mock
private MicronautBasedBean obj2;
#Before
public void setup(){
MockitoAnnotations.initMocks(this);
MockitoAnnotations.initMocks(this);
}
Is there a #PowerMockRunnerDelegate or PorwerMock runner from micronaut (like SpringRunner)
also my #Before doesntt get called to inject mocks in this case
I tried using
#MicronautTest on the TestClass but then PowerMock is not able to mock static class.
Is there a #PowerMockRunnerDelegate or PorwerMock runner from
micronaut?
Not currently, no. Feel free to file a feature request at https://github.com/micronaut-projects/micronaut-test/issues. We welcome pull requests too of course.

Use SAP Cloud SDK to integrate with a custom backend service (oData) based on VDM Generator

I followed Alexander Duemont's blog, trying to implement a Java Spring Boot application that consumes Cloud Foundry Destination. The Destination has a custom OData V2 behind it, coming from an On-Premise ERP system. For local dev, when I perform the Maven build, the Integration-Tests module registers failure due to dependency injection
This is part of my Controller
#RestController
#RequestMapping("/resources")
public class ClassificationsController {
private static final Logger logger = CloudLoggerFactory.getLogger(ClassificationsController.class);
private final ClassificationService service;
public ClassificationsController(#Nonnull final ClassificationService service) {
this.service = service;
}
…..
}
The #Nonnull final ClassificationService Service causes org.springframework.beans.factory.UnsatisfiedDependencyException
I cannot use Spring stereotype annotations on generated Service classes (Fluent) to create Beans!
This question is more likely related to Spring Boot configuration.
I'm assuming ClassificationService is an interface and the implementing class exists in the same package.
Please make sure...
... to add the implementing class of ClassificationService to your component scan / test runtime. Feel free to share the integration test code to setup the test environment. Maybe the additional class reference is missing.
... to correctly annotate the respective Application class of your Spring Boot project. For example, assuming your ClassificationService resides in org.example.services.classification, while the rest of your application uses org.example.app. Your basic Application class would look like this, when following the Cloud SDK guide:
#SpringBootApplication
#ComponentScan({"com.sap.cloud.sdk", "org.example.services.classification", "org.example.app"})
#ServletComponentScan({"com.sap.cloud.sdk", "org.example.app"})
public class Application extends SpringBootServletInitializer
{
#Override
protected SpringApplicationBuilder configure( final SpringApplicationBuilder application )
{
return application.sources(Application.class);
}
public static void main( final String[] args )
{
SpringApplication.run(Application.class, args);
}
}
... to annotate the implementing class of ClassificationService with javax.inject.Named. In case you have multiple implementations of the same interface, make sure to give the not-used class a custom (unique) value for the #Named annotation.
... to look for exceptions (Class not found) in the application log during startup.

What is the most concise way to get an injected bean for a springboot managed class?

I have a simple application that injects another component
#ComponentScan
#EnableAutoConfiguration
#Configuration
class Application {
static void main(String[] args) {
SpringApplication.run(Application, args)
}
#Bean
AuthorizationServerTokenServices tokenServices() {
return MY THING HERE
}
}
I'd like a quick/minimal way to new this up and grab the item springboot wires up (for tokenServices in this example). I'm trying to get at this to verify some configuration/settings/etc using TestNG
I should also say that I"m not using any xml to configure this (using gradle/groovy/springboot)
You can easily introduce conditional bean with the help of Spring profiles.
In your case the code would look like:
#Configuration
#Profile("tokenService")
public TestTokenServiceConfig {
#Primary
#Bean
AuthorizationServerTokenServices tokenServices() {
//implementation
}
}
The custom implementation you supply in this class will only be used by Spring in case the profile tokenService is active. The use of #Primary is needed in order to make Spring use the specified bean instead of any others present in the application context.
Also note that since you are going to be using the custom service in a test environment, you could easily mock the implementation using Mockito (or whatever other mocking framework you prefer)
And the actual integration test would be something like:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = Application.class)
#ActiveProfiles("tokenService")
class YourIntegrationTest {
#Autowired
AuthorizationServerTokenServices tokenServices;
//test
}

CDI -- #Inject not working among dependent projects

The basic architecture of my project (JBoss MSC version 1.0.2.GA-redhat-2) is like this
(VWebProj) --- >compile dependency ---> service project (QServiceProj)
(QServiceProj) ---->compile dependency ---> proxy project(VProxyProj)
(VProxyProj) ---->compile dependency ---> Manager project(VQManagerProj)
Manager project(VQManagerProj)
I have a manger class inside a Manager Project (VQManagerProj) which extends a class JDAO which in turn implements a interface VDAO
#Named("qManager")
#ApplicationScoped
public class QManager extends JDAO {...}
JDAO implements VDAO
Proxy Project (VProxyProj)
I have a proxy class inside Proxy Project (VProxyProj) which implements an interface VProxy and has the manager injected to it
#Named("vProxyImpl")
#ApplicationScoped
public class VProxyImpl implements VProxy {
#Inject #Named("qManager")
private VDao vdao;
}
Sevice Project (QServiceProj)
I have a service class inside Sevice Project (QServiceProj) which extends an abstract class
#Named
#ApplicationScoped
public class QService extends AbstractService {..}
Inside the abstract class I have the proxy injected
public abstract class AbstractService{
#Inject #Named("vProxyImpl")
private static VProxy proxy;
}
and using this proxy object the service class makes calls to the manager etc
Web Project (VWebProj)
Now I have a servlet inside the web Project (VWebProj) in which the service class is injected
#Inject
private QService qService;
The problem is that except qService none of the other injections work i.e inside QService proxy instance is null
however if I add all the injections directly in the servlet class like this
#Inject #Named("qManager")
private VDao vdao;
#Inject #Named("vProxyImpl")
private static VProxy proxy;
They are all initialized but if I go via QService they are null
I have put beans.xml in all the projects,
Thanking in advance
Charlie
As far as I know Injector can only inject objects into instances and their fields - You are trying to "inject" dependencies into static fields.
I suggest using #Singleton annotation instead - create separate instance that would hold all your current static references, and inject that singletons into Your instances instead.
#Singleton
class ProxyService {
#Inject #Named("vProxyImpl")
private VProxy proxy;
public VProxy getProxy() {
return proxy;
}
}
public abstract class AbstractService{
#Inject
private ProxyService proxyService;
}
Alternatively You can consider making VProxy singleton - I seems that what You want to obtain is just one instance of Proxy in a whole application. You need to decide yourself what is that best approach here.

How can I initialize a Java FacesServlet

I need to run some code when the FacesServlet starts, but as FacesServlet is declared final I can not extend it and overwrite the init() method.
In particular, I want to write some data to the database during development and testing, after hibernate has dropped and created the datamodel.
Is there a way to configure Faces to run some method, e.g. in faces-config.xml?
Or is it best to create a singleton bean that does the initialization?
Use an eagerly initialized application scoped managed bean.
#ManagedBean(eager=true)
#ApplicationScoped
public class App {
#PostConstruct
public void startup() {
// ...
}
#PreDestroy
public void shutdown() {
// ...
}
}
(class and method names actually doesn't matter, it's free to your choice, it's all about the annotations)
This is guaranteed to be constructed after the startup of the FacesServlet, so the FacesContext will be available whenever necessary. This in contrary to the ServletContextListener as suggested by the other answer.
You could implement your own ServletContextListener that gets notified when the web application is started. Since it's a container managed you could inject resources there are do whatever you want to do. The other option is to create a #Singleton ejb with #Startup and do the work in it's #PostCreate method. Usually the ServletContextListener works fine, however if you have more than one web application inside an ear and they all share the same persistence context you may consider using a #Singleton bean.
Hey you may want to use some aspects here. Just set it to run before
void init(ServletConfig servletConfig)
//Acquire the factory instances we will
//this is from here
Maybe this will help you.

Resources