I would like to set some common expectations on my timeServiceMock, but it is still null in before method. Any way to make it work without need to call before() in every test?
#RunWith(EasyMockRunner.class)
public class MyTest extends EasyMockSupport {
...#TestSubject and so on
#Mock
private TimeService timeServiceMock;
#Before
public void before() {
System.out.println(this.timeServiceMock);
}
...tests
}
Am I missing something?
It looks like EasyMockRunner only creates and injects mocks in #Test.
so if you want to use it in a #Before, remove the #Mock annotation from TimeService and create the mock yourself in #Before. Then you will have to inject the mock yourself into the #TestSubject.
So something like this:
#RunWith(EasyMockRunner.class)
public class MyTest extends EasyMockSupport {
#TestSubject and so on
Foo testSubject = ...
private TimeService timeServiceMock;
#Before
public void before() {
this.timeServiceMock = createMock(TimeService.class);
...
}
#Test
public void mytest(){
testSubject.setTimeService(timeServiceMock);
...
}
}
Related
How can I use/inject the result of one mock into another?
I think I did it in the wrong way
The int param is always null
I use spy because the method I test is void.
Can I do it using mockito?
#RunWith(MockitoJUnitRunner.class)
public class Test {
#Mock
Utils utils;
#Mock
Custom custom;
#Spy
#InjectMocks
MyService service;
#Test
public void test(){
Mockito.when(utils.get("p")).thenReturn(1); //use result of it in the next mock call
Mockito.when(custom.isValid(1)).thenReturn(true); //custom use 1 here
Mockito.doCallRealMethod().when(service).doIt("p");
service.doIt("p");
Mockito.verify(service,Mockito.times(1)).doIt("p");
}
}
#Service
public class MyService {
Utils utils;
Custom custom;
public MyService(Utils utils) {
this.utils = utils;
}
public void doIt(String value){
int param = utils.get(value);
if(custom.isValid(param)){
//do it
}
}
}
You don't actually need to Spy MyService. You can simplify your test and get it to work:
#RunWith(MockitoJUnitRunner.class)
public class Test {
#Mock
Utils utils;
#InjectMocks
MyService service;
#Test
public void test(){
// Arrange
Mockito.doReturn(1).when(utils.get("p"));
Mockito.when(custom.isValid(1)).thenReturn(true);
// Act
service.doIt("p");
// Assert
Mockito.verify(utils, Mockito.times(1)).get("p");
// You should also confirm that whatever is done in `if(param==1)` is actually done
}
}
You're mocking with wrong parameter, change your test like that:
public class Test {
#Mock
Utils utils;
#InjectMocks
MyService service;
#BeforeEach
void setUp(){
initMocks(this);
}
#Test
public void test(){
Mockito.when(utils.get(any())).thenReturn(1);
service.doIt("p");
Mockito.verify(utils).get(any());
}
}
Instead any() you can put any another variable but it should be the same variable with variable which you call the service
I'm using spring-boot-starter-test 2.2.0 which includes Mockito 3.1.0.
I would like to test this class:
#RestController
public class MyClass {
#Autowired MyAutowired myAutowired;
public int myClassMethod(int i) {
return myAutowired.methodToMock(i);
}
}
Which use this one:
#Service
public class MyAutowired {
public int methodToMock(int i) {
return i;
}
}
In my test I would like to run myClassMethod but with a mocked behavior for methodToMock. Ideally I would like to check if methodToMock was called with the expected argument.
Here is what I tried so far:
#SpringJUnitConfig(Config.class)
#WebAppConfiguration
#ExtendWith(MockitoExtension.class)
class MyClassTest {
#Autowired MyClass myClass;
#Mock
private MyAutowired myAutowired;
#BeforeEach
public void initMocks(){
MockitoAnnotations.initMocks(this);
}
#Test
public void myTest() {
Mockito.when(myAutowired.methodToMock(any()).thenReturn(1);
int shouldBe1ButIs2 = myClass.myClassMethod(2);
}
}
What's wrong with that ? And how to make myClass.myClassMethod(2) return 1 ?
The issue is that your object MyClass is not referring to the right mock instance. The MyAutowired has to injected into MyClass.
You have two options:
Creating a setMyAutowired method in MyClass and pass the MyAutowired instance to it in your test class.
Replacing #Autowired with #InjectMocks annotation on MyClass. In this way, an instance of MyClass will be created and mocks objects which you declared in your test will be injected automatically in it.
I normally use the second option, which is more elegant.
My FixValueConceptIntegration class has a constructor and it looks like this:
private ReferenceConceptHelper referenceConceptHelper;
private ConceptClientFacade conceptClientExternalFacade;
public FixValueConceptIntegration()
{
referenceConceptHelper = JournalSingletonFactory.getInstance().getSingletonInstance(ReferenceConceptHelper.class);
conceptClientExternalFacade = JournalSingletonFactory.getInstance().getSingletonInstance(ConceptClientFacade.class);
}
So now I'm going to test it using Mockito.
If we have a constructor like
public FixValueConceptIntegration(ReferenceConceptHelper referenceConceptHelper, ConceptClientFacade conceptClientExternalFacade)
{
this.referenceConceptHelper = referenceConceptHelper
this.conceptClientExternalFacade = conceptClientExternalFacade
}
I know it is easy to initialize when we are going to testing the class. Because we can just mock the ReferenceConceptHelper and ConceptClientFacade classes.
Then we can use it at the #BeforeMethod like this:
#BeforeMethod
public void beforeMethod()
{
MockitoAnnotations.initMocks(this);
fixValueConceptIntegration = new FixValueConceptIntegration(referenceConceptHelper, conceptClientExternalFacade);
}
Then all the dependencies will inject to the constructor and no worries.
So here the problem is I can't figure out how to inject these dependencies (by mocking) to the above testable class.
Just use the mock (org.mockito.Mockito.mock) method for the class and the when method to mock the method calls:
#Test
public void yourTest() {
ReferenceConceptHelper referenceConceptHelper = mock(ReferenceConceptHelper .class);
when(referenceConceptHelper.someMethod(any()).thenReturn("hello");
ConceptClientFacade conceptClientExternalFacade = mock(ConceptClientExternalFacade.class);
when(conceptClientExternalFacade.someMethod(any()).thenReturn("world");
FixValueConceptIntegration integration = new FixValueConceptIntegration(referenceConceptHelper, conceptClientExternalFacade);
assertEquals("hello world", integration.methodThatYouWouldLikeToTest());
}
In this case, you do not need to use the #BeforeMethod or call MockitoAnnotations.initMocks(this);. For unit tests, the initMocks are only useful if you do not have access directly to the class injected (typically when you are using field injection).
But if you would like to use the annotations (I personally don't like), you can do something like that:
#InjectMocks
private FixValueConceptIntegration integration;
#Mock
private ReferenceConceptHelper referenceConceptHelper;
#Mock
private ConceptClientFacade conceptClientFacade;
#Before
public void init() {
MockitoAnnotations.initMocks(this);
when(referenceConceptHelper.someMethod(any()).thenReturn("hello");
when(conceptClientExternalFacade.someMethod(any()).thenReturn("world");
}
#Test
public void yourTest() {
assertEquals("hello world", integration.methodThatYouWouldLikeToTest());
}
I extended my test class with TestNGBase which extends PowerMockTestCase.
And then add registerMockSingleton method to the TestNGBase class like this;
protected <E, I extends E> void registerMockSingleton(Class<E> typeInterface, I mock)
{
delegate.registerMockSingleton(typeInterface, mock);
}
Then inject mock dependencies to the constructor like this way;
#Override
public void performSetup() {
MockitoAnnotations.initMocks(this);
registerMockSingleton(ReferenceConceptHelper.class,mockReferenceConceptHelper);
registerMockSingleton(ConceptClientFacade.class,mockConceptClientExternalFacade);
fixValueConceptIntegration = new FixValueConceptIntegration();
}
#Override
protected void performTearDown() throws Exception
{
fixValueConceptIntegration = null;
}
All solved!!!
(My testable class constructor doesn't inject dependencies to with constructor
arguments.Thats why I solved my problem like this)
I am trying to set up my class to be used in Junit.
However when I try to do the below I get an error.
Current Test Class:
public class PersonServiceTest {
#Autowired
#InjectMocks
PersonService personService;
#Before
public void setUp() throws Exception
{
MockitoAnnotations.initMocks(this);
assertThat(PersonService, notNullValue());
}
//tests
Error:
org.mockito.exceptions.base.MockitoException:
Cannot instantiate #InjectMocks field named 'personService'
You haven't provided the instance at field declaration so I tried to construct the instance.
However the constructor or the initialization block threw an exception : null
How can I fix this?
You are not mocking anything in your code. #InjectMocks sets a class where a mock will be injected.
Your code should look like this
public class PersonServiceTest {
#InjectMocks
PersonService personService;
#Mock
MockedClass myMock;
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
Mockito.doReturn("Whatever you want returned").when(myMock).mockMethod;
}
#Test()
public void testPerson() {
assertThat(personService.method, "what you expect");
}
Another solution is to use #ContextConfiguration annotation with static inner configuration class like so:
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(loader = AnnotationConfigContextLoader.class)
public class PersonServiceTest {
#Autowired
PersonService personService;
#Before
public void setUp() throws Exception {
when(personService.mockedMethod()).thenReturn("something to return");
}
#Test
public void testPerson() {
assertThat(personService.method(), "what you expect");
}
#Configuration
static class ContextConfiguration {
#Bean
public PersonService personService() {
return mock(PersonService.class);
}
}
}
Anyway, you need to mock something that the method you want to test uses inside to get desired behaviour of that method. It doesn't make sense to mock the service you're testing.
You're misunderstanding the purpose of the mock here.
When you mock out a class like this, you are pretending as if it's been injected into your application. That means you don't want to inject it!
The solution to this: set up whatever bean you were intending to inject as #Mock, and inject them into your test class via #InjectMocks.
It's unclear where the bean you want to inject is since all you have is the service defined, but...
#RunWith(MockitoJUnitRunner.class);
public class PersonServiceTest {
#Mock
private ExternalService externalSvc;
#InjectMocks
PersonService testObj;
}
If I am not mistaken...the thumb rule is you cannot use both together..you either run unit test cases with using MockitojunitRunner or SpringJUnitRunner you cannot use both of them together.
I am trying to unit test a method, which has different branches depending upon the value of an object that is created inside it. The below code demonstrates it.
public class AClass {
public void method2() {
//Some code goes here
}
public void method1(BClass bObject) {
C_Class cObject = bObject.someMethodThatReturnsC();
if(cObject != null) {
method2();
method2();
}
}}
Below is the TestClass:
public class AClassTest {
#InjectMocks
AClass AClassSpy;
#Mock
BClass b_objectMock;
#Mock
C_Class c_objectMock;
#BeforeMethod
public void beforeMethod() {
AClassSpy = spy(new AClass());
MockitoAnnotations.initMocks(this);
}
public void method1Test () {
doReturn(c_objectMock).when(b_objectMock).someMethodThatReturnsC());
AClassSpy.method1(b_objectMock);
verify(AClassSpy, times(2).method2();
}
}
However, it always FAILS, since the c_objectMock is always null. What do I do to tell Mockito to not to return a null object?
It works good, just use #Before annotation from junit, not #BeforeMethod, and mark your test method like #Test and remove second bracket from
doReturn(c_objectMock).when(b_objectMock).someMethodThatReturnsC())<-this one;
and add bracket at verify:
verify(AClassSpy, times(2)<-here.method2();
And just take care of your code!
This should work:
public class AClassTest {
#InjectMocks
private AClass AClassSpy;
#Mock
private BClass b_objectMock;
#Mock
private C_Class c_objectMock;
#Before
public void beforeMethod() {
AClassSpy = spy(new AClass());
MockitoAnnotations.initMocks(this);
}
#Test
public void method1Test() {
doReturn(c_objectMock).when(b_objectMock).someMethodThatReturnsC();
AClassSpy.method1(b_objectMock);
verify(AClassSpy, times(2)).method2();
}
}
Instead of before method you can use annotation #RunWith. It looks clearly:
#RunWith(MockitoJUnitRunner.class)
public class AClassTest {
#Spy
#InjectMocks
private AClass AClassSpy;
#Mock
private BClass b_objectMock;
#Mock
private C_Class c_objectMock;
#Test
public void method1Test() {
doReturn(c_objectMock).when(b_objectMock).someMethodThatReturnsC();
AClassSpy.method1(b_objectMock);
verify(AClassSpy, times(2)).method2();
}
}
You are having this behaviour because you are not mocking property the call to someMethodThatReturnsC.
It should be:
doReturn(c_objectMock).when(b_objectMock).someMethodThatReturnsC();