How I can mock A with B mock as constructor parameter?
private B actionContext;
private A target;
#BeforeEach
void setUp() {
actionContext = mock(B.class);
target = mock?
}
public class A {//...
public A(B b){//...
}
}
You can use the mockito annotation
#Mock
private B mockB;
#Spy
#InjectMocks
private A testObj = new A(mockB);
set up test behavior in setUp method...
when(mockB.method()).thenReturn();
if you want to mock class A methods you don't need to mock class B
mocking class A is enough
#BeforeEach
void setUp() {
A mockedA = mock(A.class);
}
And if you want to use mocked methods of class B you can mock it separately
#BeforeEach
void setUp() {
A mockedA = mock(A.class);
B mockedB = mock(B.class);
}
also will suggest you to read Mockito docs to understand mocking principles .
Related
Hi I am trying to test service layer. I have already wrote tests for ConverterFactory. I think I need the mock dependency classes which ConverterServiceImpl using but Still I got NullPointerException
This is my service class
#Service
#RequiredArgsConstructor
public class ConverterServiceImpl implements ConverterService {
ConverterFactory factory = new ConverterFactory();
private final WebLinkRepository webLinkRepository;
private final DeepLinkRepository deepLinkRepository;
#Override
public DeepLinkResponse toDeepLink(WebLinkRequest webLinkRequest) {
WebLink webLink;
String url = webLinkRequest.getUrl();
Converter converter = factory.getConverter(url);
webLink = new WebLink();
webLink.setUrl(url);
String convertedUrl = converter.toDeepLink(url);
webLink.setConvertedUrl(convertedUrl);
webLinkRepository.save(webLink);
return new DeepLinkResponse(convertedUrl);
}
}
And this is the test
#RunWith(MockitoJUnitRunner.class)
public class ConverterServiceImplTest {
#InjectMocks
ConverterServiceImpl converterService;
#Mock
WebLinkRepository webLinkRepository;
#Mock
DeepLinkRepository deepLinkRepository;
#Mock
ConverterFactory converterFactory;
#Mock
ProductConverter productConverter;
#Mock
WebLinkRequest webLinkRequest;
#BeforeAll
void init(){
webLinkRequest.setUrl(WEBLINK_ONLY_PRODUCT);
}
#Test
public void toDeepLink_only_content_id() {
ConverterFactory converterFactory = mock(ConverterFactory.class);
when(converterFactory.getConverter(any())).thenReturn(productConverter);
DeepLinkResponse deepLinkResponse = converterService.toDeepLink(webLinkRequest);
assertEquals(deepLinkResponse.getUrl(),"ty://?Page=Product&ContentId=1925865");
}
}
This code throws error says. What am i doing wrong here?:
java.lang.NullPointerException
at com.example.converter.service.factory.ConverterFactory.getConverter(ConverterFactory.java:13)
You don't need to create a ConverterFactory converterFactory = mock(ConverterFactory.class) a second time in your test method, since you have already created such mock as a class field.
Besides, you did not inject the mock created in the test method into the class under test, whereas the mock, created as a field, was injected using #InjectMocks annotation.
So just remove ConverterFactory converterFactory = mock(ConverterFactory.class) from test method:
#RunWith(MockitoJUnitRunner.class)
public class ConverterServiceImplTest {
#InjectMocks
ConverterServiceImpl converterService;
#Mock
ConverterFactory converterFactory;
// other stuff
#Test
public void toDeepLink_only_content_id() {
when(converterFactory.getConverter(any())).thenReturn(productConverter);
// other stuff
converterService.toDeepLink(webLinkRequest);
}
}
How can I mock a member class in another class which has already been spied by PowerMockito.spy()?
#Component
public class BoxFileDao {
#Autowired
private BoxFileService boxFileService;
public void uploadFile() {
.....
boxFileService.uploadFile(user, credential);
}
}
#RunWith(PowerMockRunner.class)
#PrepareForTest(BoxFileDao.class)
public class BoxFileDaoTest {
#Test
public void testUploadFile() {
BoxFileDao mock = PowerMockito.spy(new BoxFileDao());
(how do I get the boxFileService from mock?)
mock.uploadFile();
verify(boxFileService).uploadFile(user, credential);
}
}
You can use #InjectMock to inject the mocked boxFileService object in the real boxFileDao object. Your test class can be written something like
#RunWith(PowerMockRunner.class)
public class BoxFileDaoTest {
#Mock
private BoxFileService boxFileService;
#InjectMocks
private BoxFileDao boxFileDao;
#Test
public void testUploadFile() {
boxFileDao.uploadFile();
verify(boxFileService).uploadFile(user, credential);
}
}
First you create your class under test BoxFileDao while injecting the mock for boxFileService into it. Afterwards you can create the spy on it.
For example:
BoxFileDao dao = new BoxFileDao();
dao.boxFileService = Mockito.mock(BoxFileService.class);
BoxFileDao spy = Mockito.spy(dao);
But the question would be why do you even want to do that? Is there a reason to spy on BoxFileDao, your class under test?
I think there is either a basic misunderstanding on my part with how when works, or more specifically how Mockito is working.
I have a service class that has a utility class injected via constructor. The utility class has some other dependencies autowired by constructor as well.
A service class method calls several methods in the utility class. The test uses when/thenReturn statements on the called utility methods. When I make a call on the service method, I get an NPE on a utility method called with a null parameter. But I expected parameters set in the when clause to be set. Code below:
#Service
public class ServiceClass {
private Utility utility;
public ServiceClass(Utility utility) {
this.utility = utility;
}
public serviceMethod(MyDocument myDocument, List<Attachment> attachments) {
SomeType variable1;
OtherType variable2;
List<String> stringList;
long time;
time = utility.method1(variable1, variable2);
stringList = utility.method2(myDocument, attachments.get(0));
...
}
#Service
public class Utility {
private Dependency1 depend1;
private Dependency2 depend2;
public Utility(Dependency1 depend1, Dependency2 depend2) {
this.depend1 = depend1;
this.depend2 = depend2;
}
public long method1(SomeType var1, OtherType var2) {
....
}
public List<String> method2(MyDocument myDoc, Attachment attach) {
....
}
Now the test code looks as follows:
public TestClass {
private ServiceClass serviceClass;
#Mock
private Depend1 depend1;
#Mock
private Depend2 depend2;
#InjectMocks
private Utility utility;
#Rule
public MockitoRule rule = MockitoJUnit.rule();
#Before
public void setup() {
serviceClass = new ServiceClass(utility);
}
#Test
public testServiceMethod() {
long time = System.currentTimeMillis();
MyDocument doc = new MyDocument();
List<Attachments> attachments = Arrays.asList(new Attachment(...), new Attachment(...));
SomeType some = new SomeType();
OtherType other = new OtherType();
when(utility.method1(some, other)).thenReturn(time);
when(utility.method2(doc, attachments.get(0)).thenReturn(Arrays.asList(new String("stg 1"), new String("stg 2"));
String resp = serviceClass.serviceMethod(doc, attachments);
assertEquals("service completed", resp);
}
}
But when utility.method2 is called, myDocument shows as null. I was expecting that it would be an instance of MyDocument.
Do I have something misconfigured? Am I missing a concept here? All help appreciated!
Thanks.
UPDATE
Corrected the arguments to the serviceMethod.
The ServiceClass is the class you are testing, so you should anotate with #Mock only the dependencies of this class in your test, in your case the utility attribute, remove Depend1 and Depend1 declarations. The setup method is not necessary, you can anotate serviceClass in your test with #InjectMocks instead, it take cares of the injections automatically. And finally, your TestClass need the #RunWith(MockitoJunitRunner.class) to make everything work if it's not there.
#RunWith(MockitoJunitRunner.class)
public class TestClass{
#InjectMocks
private ServiceClass serviceClass;
#Mock
private Utility utility;
}
This is a basic definition for your TestClass, the test itself looks correct, but can be improved to use ArgumentMatchers on the "when" clause and add a verify clause using ArgumentCaptor to validate the parameters.
I have a JUnit test that reads
public class EventHandlerTest {
#Mock
ThreadPoolExtendedExecutor threadPoolExtendedExecutor;
private EventHandler handler;
private Map<Queue<SenderTask>> subBuffers = new HashMap<>();
#Before
public void setUp() {
// PROBLEM: threadPoolExtendedExecutor null!
handler = new EventHandler(subBuffers, threadPoolExtendedExecutor);
}
}
When I call new in setUp, I have threadPoolExtendedExecutor=null.
I would like to insert some mocked threadPoolExtendedExecutor so, I do not have NullPointer problems when calling its methods (so simple interface mock is enough for me at this moment)
You can simply mock it using (in setUp)
threadPoolExtendedExecutor = mock(ThreadPoolExtendedExecutor.class);
#Before
public void setUp() {
threadPoolExtendedExecutor = mock(ThreadPoolExtendedExecutor.class);
handler = new EventHandler(subBuffers, threadPoolExtendedExecutor);
}
You can also let MockitoJUnitRunner do it for you :
don't forget to inject mocks in your service under test by annotating it with #InjectMocks
#RunWith(MockitoJUnitRunner.class)
public class EventHandlerTest {
#Mock
ThreadPoolExtendedExecutor threadPoolExtendedExecutor;
If you would like to use the #Mock or #InjectMocks annotations on the test class fields then you need to add #RunWith(MockitoJUnitRunner.class) at the class level.
#RunWith(MockitoJUnitRunner.class)
public class EventHandlerTest {
#Mock
ThreadPoolExtendedExecutor threadPoolExtendedExecutor;
Another approach is to not use the above annotations and manually create mocks by calling org.mockito.Mockito.mock().
I have something like this:
public class Class1 {
#Autowired
Class2 class2;
public Object class1Method {
// Do something
Object obj = class2.class2Method(arg);
// Do something with obj
return somthing;
}
}
I am doing unit testing to Class1 and I want to mock the class2Method. I tried to find solution and I found this:
Test class with a new() call in it with Mockito
I understood that this solution works if I do new instance of Class2 in the class1Method, but in my case I use Spring Dependency Injection and I can't figure out how to this.
Depending on how did you build your DI with spring you can use something like this if you have #Autowired on field
#RunWith(SpringRunner.class)
public Class1Test {
#InjectMocks
#Autwired
private Class1 class1;
#Mock
Class2 class2;
#BeforeMethod
public void initMocks(){
MockitoAnnotations.initMocks(this);
}
#Test
public Object testClass1Method {
when(class2.class2Method(anyString()).thenReturn(expectedReturn);
//Now test whatever you need with mocked class2.class2Method
}
}
It's much easier and you don't need to have spring context up for tests if you have constructor DI (#Autowired on constructor)
public Class1Test {
private Class1 class1;
private Class2 class2;
#BeforeMethod
public void initMocks(){
class2 = mock(Class2.class);
class1 = new Class1(class2);
}
//then use the same approach to mock any methods that you need
}
You should go with
Mockito
,and have your JUnit class include this at the top #RunWith(MockitoJUnitRunner.class). So in your case you can have your Junit like this.
#RunWith(MockitoJUnitRunner.class)
public Class1Test {
#InjectMocks
private Class1 class1 = new Class1();
#Mock
Class2 class2;
#Test
public Object testClass1Method {
// Now this will get the class2 mock instance when executed
Object obj = class1.class1Method(arg);
}
}
This is how you can write Unit test for Class1 using Mockito :
public Class1Test {
#InjectMocks
private Class1 class1;
#Mock
private Class2 class2;
#BeforeMethod
public void initMocks(){
MockitoAnnotations.initMocks(this);
}
#Test
public void test_method1() {
Object obj = //instantiate it here...,
Mockito.doReturn(obj).when(class2.class2Method(anyString());
Assert.assertEquals(class1.class1Method(), something);
}
}