I want to use both #Autowired and #Mock.
For Example, I don't want to mock conversionService, I want to autowire it and mock other services.
Related
I have 3 services
class Service1{
#Inject private Service2 service2;
}
class Service2{
#Inject private Service3 service3;
}
class Service3{
public Object test(){
...}
}
class TestService1{
//do a test and mock the method in service3
when(service3.test()).doReturn(Something());
}
I have to mock the method in service 3 injected in service 2 which is injected in service 1
any idea? I have to test it directly like that I have no other way to do it.
As the last service is a call to a rest Service, i created an interface IServiceC then 2 implementations of it, one in the main/src/java, another in test/src/java and all services are returned hardcoded values. because the complexity here is to say ok i will inject all service but not the last, and tell to second layer i inject you but i mock you too etc...
very too complicated to manage, with a mock class implementation i don't have to cary about this topic, i use arquillian and all will be injected (i exclude from the war package the default implementation and add the mock implementation to the war)
In my portlet, I'm using MultiVMPoolUtil.getPortalcache("test")
This portet needs to be tested.. For this Mockito
Mock.. Try to set portalcache using mock of above class..
But mock the above class is not running in junit
... When we mock MultiVMPoolUtil
The mockito junit test states that .. Cannot able to mock the liferay
MultiVMpoolutil.class
#Mock
private MultiVmpoolutil
#Before
public void setup()
How to mock this class.. Is there any other way to slove this?
Static classes can be mocked with PowerMock. It´s also my last sword for fighting against util classes. furthermore it also allows very deep manipulation opportunities, like suppressing constructors of super classes or even static initializers (helpful when mocking the PropsUtil).
https://github.com/powermock/powermock
https://github.com/powermock/powermock/wiki/Suppress-Unwanted-Behavior
I was using #RunWith(MockitoJUnitRunner.class) for my junit test with mockito. But now i am working with spring boot app and trying to use #RunWith(SpringRunner.class) . Does using #RunWith(SpringRunner.class) has any advantages over using #RunWith(MockitoJUnitRunner.class)? Can i still use feature like #Injectmock, #Mock, #Spy with #RunWith(SpringRunner.class)
The SpringRunner provides support for loading a Spring ApplicationContext and having beans #Autowired into your test instance. It actually does a whole lot more than that (covered in the Spring Reference Manual), but that's the basic idea.
Whereas, the MockitoJUnitRunner provides support for creating mocks and spies with Mockito.
However, with JUnit 4, you can only use one Runner at a time.
Thus, if you want to use support from Spring and Mockito simultaneously, you can only pick one of those runners.
But you're in luck since both Spring and Mockito provide rules in addition to runners.
For example, you can use the Spring runner with the Mockito rule as follows.
#RunWith(SpringRunner.class)
#SpringBootTest
public class MyTests {
#Rule
public MockitoRule rule = MockitoJUnit.rule();
#Mock
MyService myService;
// ...
}
Though, typically, if you're using Spring Boot and need to mock a bean from the Spring ApplicationContext you would then use Spring Boot's #MockBean support instead of simply #Mock.
When SpringRunner.class is used, Spring provides corresponding annotations:
#MockBean
#SpyBean
Mocks are injected to objects under tests via #Autowired annotation. To enable this functionality tests must be annotated with
#SpringBootTest
or
#TestExecutionListeners(MockitoTestExecutionListener.class)
More details and examples can be found in the official documentation: Mocking and Spying Beans
As per the JavaDoc:
SpringRunner is an alias for the SpringJUnit4ClassRunner.
To use this class, simply annotate a JUnit 4 based test class with #RunWith(SpringRunner.class).
If you would like to use the Spring TestContext Framework with a runner other than this one, use org.springframework.test.context.junit4.rules.SpringClassRule and org.springframework.test.context.junit4.rules.SpringMethodRule.
And the JavaDoc of TestContext:
TestContext encapsulates the context in which a test is executed, agnostic of the actual testing framework in use.
That of method getApplicationContext():
Get the application context for this test context, possibly cached.
Implementations of this method are responsible for loading the application context if the corresponding context has not already been loaded, potentially caching the context as well.
So, SpringRunner does load the context and is responsible for maintaining it. For example, if you want to persist data into an embedded database, like H2 in-memory database, you have to use SpringRunner.class; and, to clean the tables to get rid of the records you inserted after every test, you annotate the test with #DirtiesContext to tell Spring to clean it.
But, this is already an integration or component test. If your test is pure unit test, you don't have to load DB, or you just want to verify some method of a dependency is called, MockitoJUnit4Runner suffices. You just use #Mock as you like and Mockito.verify(...) and the test will pass. And it is a lot quicker.
Test should be fast. As fast as possible. So whenever possible, use MockitoJUnit4Runner to speed it up.
Scenario 2019 November : spring-boot : 2.1.1.RELEASE
You have a spring boot api rest
You need to test a service called MySuperSpringService
But, inside MySuperSpringService, are required two more autowires. One to perform a sql select (MyJpaRepository) and another to call an external api rest (MyExternalApiRest)
#Service
public class MySuperSpringService {
#Autowired
private MyRepository innerComponent1;
#Autowired
private MyExternalApiRest innerComponent2;
public SomeResponse doSomething(){}
}
How test MySuperSpringService mocking database and external api rest ?
So, in order to test this service MySuperSpringService which needs another spring beans: MyJpaRepository and MyExternalApiRest, you need to mock them using #MockBean and create the result as you need.
import static org.mockito.Mockito.when;
import java.io.IOException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit4.SpringRunner;
import junit.framework.TestCase;
#RunWith(SpringRunner.class)
#SpringBootTest(classes = your.package.Application.class)
public class MySuperSpringServiceTest extends TestCase {
#Autowired
private MySuperSpringService serviceToTest;
#MockBean
private MyRepository myRepository;
#MockBean
private MyExternalApiRest myExternalApiRest;
#Before
public void setUp() {
Object myRepositoryResult = new Object();
//populate myRepositoryResult as you need
when(myRepository.findByClientId("test.apps.googleusercontent.com"))
.thenReturn(myRepositoryResult);
Object myExternalApiRestResult = new Object();
//populate myExternalApiRestResult as you need
when(myExternalApiRest.listUserRoles("john#doe.com")).thenReturn(myExternalApiRestResult);
}
#Test
public void testGenerateTokenByGrantTypeNoDatabaseNoGoogleNoSecurityV1(){
SomeResponse response = serviceToTest.doSomething();
//put your asserts here
}
}
you can absolutely use SpringRunner for both unit tests and integration tests.
SpringRunner Tutorial
I've been doing some work with sling models for a project and in the process created a couple of custom injectors. Everything seems to work great when implemented (used in AEM). However, when I'm testing the custom injectors are not getting run.
Here's an example of what I currently have set up
In MyModel
#Inheritable
#CustomAnnotation("foo")
private String _foo
In test (tests using wcm.io mocking Libraries)
#Rule
AemContext context = new AemContext(ResourceResolverType.RESOURCERESOLVER_MOCK);
//required by the injector
#Mock
InheritanceService _inheritanceService;
#Mock
InheritableInjector _inheritanceInjector;
#Before
public void setup() {
context.registerService(InheritanceService.class, _inheritanceService);
context.registerService(InheritableInjector.class, _inheritanceInjector);
context.addModelsForPackage("com.package.example.models");
//use this resource in tests to adaptTo(MyModel.class)
_resource = context.load().json("myJson.json", "/myPath");
}
... tests
The tests compile and run, but the Injector isn't being executed. I know it's registered because when I don't have the Injector's dependent services registered in the context I get an error. When I debug through it, none of the breakpoints are hit. I'm wondering if I need to also register the "Inheritable" annotation somewhere or if anyone just has any general information on how I can get the custom injector to execute.
thank you
I was able to figure out my error. So the important thing to remember about Sling Model Injectors is that they are just OSGI services (something I completely let myself get away from).
So just treating them like normal services and then remembering to annotate the Injector with #InjectMocks was what I needed to do in order to fix the error.
The following now works great.
#Mock
InheritanceService _inheritanceService; //injector dependency
#InjectMocks
InheritanceInjector _inheritanceInjector;
#Before
public void setup() {
context.registerService(InheritanceService.class, _inheritanceService);
context.registerService(InheritableInjector.class, _inheritanceInjector);
}
hopefully that helps anyone that might run into the issue. If anyone can make this answer better please feel free to reply/edit.
I am using junit, mockito and mockMVC to test the working of a webapp. I am struggling with a dependency whose injecttion I cannot figure out. My webapp structure is as follows.
Class Controller{
#Autowired Service searchService;
#RequestMapping("Search")
public returnType search(#RequestParam("parameter")String parameter){
searchService.doSearch(parameter);
}
}
and the service class
Class Service{
#Autowired Service2 service2;
public returnType doSearch(String parameter){
//some code
service2.call(parameter);
}
}
I need to test the search method for this controller, however service2 is not currently live and hence calls to it have to be mocked. I can mock service2, but cannot figure out how to inject a mock of service2 in my mockMVC instance of controller. As far as I know #InjectMocks in mockito only injects mocks one level deep and not two.
EDIT:
I am using the following to get MockMVC instance of controller
MockMvc controller;
controller = MockMvcBuilders.standaloneSetup(Controller);
What you are essentially want to do is mock a bean.
In your case, you have to mock bean for service2 using #MockBean annotations.
Please refer this article for details.
You don't need that.
Mocking search service will be sufficient as you get the handle of what needs to be done.
Example:
doReturn(...).when(searchService).doSearch(any());
While performing Unit Testing, the developer need to identify the System Under Test and mock/stub all the collaborators.
So, in this case you would write a separate unit test for Controller and Search Service.
Also, read this brilliant article by Martin Fowler - Mocks Aren't Stubs.