I have an abstract class like this
public abstract class MyClass {
final Clock clock;
Myclass(Clock clock) {
this.clock = clock;
}
public void myMethod() {
Long time = clock.now().getMillis(); // I get exception here.
return true;
}
}
Now I'm writing tests like this:
class MyClassExtender extends MyClass {
Myclass(Clock clock) {
super(clock);
}
}
In the same file
public class MyClassTest {
private static final Long NOW = "283748L";
#Rule
public final Mocks mocks = new Mocks(this);
#Mock
private Clock clockMock;
private myObject = new MyClassExtender(clockMock);
#Before
#SuppressWarnings("unchecked")
public void setup() throws Exception {
myClassSpy = Mockito.spy(myObject);
}
public void testMethod() {
Mockito.when(clockMock.now().getMillis()).thenReturn(NOW);
assertThat(myClassSpy.myMethod()).isTrue();
}
}
This throws a NullPointerException at the line I've mentioned above. What am I doing wrong ? FYI: The now() returns an 'Instant' class object.
Do you use proper runner, ie. MockitoJUnitRunner?
However I believe that clockMock is initialized only after object creation, ie. your myObject will receive null as parameter.
Try to initialize myObject only in #Before section.
Related
I have the below flow
#InjectMocks private ClassToTest classToTest;
#Mock private ClassToInject classToInject;
#Before
public void setup() {
initMocks(this);
}
#Test
public void test() {
Classx mockClassObj = Mockito.mock(Classx.class);
when(classToInject.publicMethod1(mockClassObj)).thenReturn(1000);
classToTest.publicMethod();
}
I want to test public method of classToTest. Now this method makes call to a private method, which I am not mocking. Inside this private method another public method is called, which I want to mock publicMethod1. Instead of the private method making use of value 1000 it is behaving as if the publicMethod1 was not mocked and I get NPE inside the flow of the method somewhere. I tried using #Spy with classToTest and also I am using init.mocks/#RunWith but it fails.
In short it is something like
ClassToTest. publicMethod --> ClassToTest.privateMethod(not mocking) --> ClassToInject.publicMethod1(want to mock)
The class looks like below
class ClassToTest {
#Inject ClassToInject classToInject;
public publicMethod() {
privateMethod();
}
private privateMethod() {
int x = classToInject.publicMethod1();
// use the return value
// throw exception
}
You mock classToInject.publicMethod1(mockClassObj) not classToInject.publicMethod1().
But your code invoked classToInject.publicMethod1();
int x = classToInject.publicMethod1(); // you invoked no parameter method
Check method which you want to invoke.
If You want to invoke classToInject.publicMethod1(), reference this code
#RunWith(MockitoJUnitRunner.class)
public class MockedTest {
#InjectMocks
private ClassToTest classToTest;
#Mock
private ClassToInject classToInject;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
#Test
public void test() {
Mockito.when(classToInject.publicMethod1())
.thenReturn(1000);
classToTest.publicMethod();
}
}
class ClassToTest{
ClassToInject classToInject;
public void publicMethod() {
privateMethod();
}
private int privateMethod() {
int x = classToInject.publicMethod1();
throw new NullPointerException(String.valueOf(x));
}
}
class ClassToInject{
public int publicMethod1() {
return 0;
}
}
The result is 1000 success
java.lang.NullPointerException: 1000
I want to test a method which creates an object of another class using it's parameterized constructor. Even though I've mocked the constructor of MyClass, it makes the third party library which is in constructor implementation and results in the error. I'm using Mockito/PowerMockito.
public class MyClass{
private MyObj obj;
MyClass (String profile)
{
//some 3rd party library call
obj = thridPartyLib.someMethod(profile);
}
public String someMethod(){
return obj.someExternalCall();
}
}
Class which I want to test
public class ClassTobeTested{
public void execute(){
//some code
// ......
MyClass myClass = new MyClass(profile);
myclass.someMethod();
}
}
What I tried so far - classUnderTest.execute() ends up calling the thridPartyLib.someMethod(profile); which is part of MyClass constructor.
#RunWith(PowerMockRunner.class)
#PrepareForTest(MyClass.class)
public class ClassTobeTestedTest {
private MyClass mockMyClass;
private ClassTobeTested classUnderTest;
#Before
public void init() {
classUnderTest = new ClassTobeTested();
mockMyClass = PowerMockito.mock(MyClass.class);
}
#Test
public void testExecute(){
PowerMockito.whenNew(MyClass.class)
.withArguments(Mockito.any())
.thenReturn(mockMyClass);
classUnderTest.execute();
}
}
Your code will work only if you are working with a spy or mock of classUnderTest. Try this. This should work
#RunWith(PowerMockRunner.class)
#PrepareForTest( {MyClass.class, ClassTobeTested.class })
public class ClassTobeTestedTest {
private MyClass mockMyClass;
private ClassTobeTested classUnderTest;
#Before
public void init() {
classUnderTest = spy(new ClassTobeTested());
mockMyClass = PowerMockito.mock(MyClass.class);
}
#Test
public void testExecute() throws Exception {
PowerMockito.whenNew(MyClass.class)
.withArguments(Mockito.any())
.thenReturn(mockMyClass);
classUnderTest.execute();
}
}
The pain might suggest another approach. Consider injecting a Factory into ClassTobeTested which knows how to create an instance of MyObj. For example:
class MyObjFactory {
MyObj create(String profile) {
return new MyClass(profile);
}
}
then
public class ClassTobeTested {
private final MyObjFactory factory;
public ClassTobeTested(MyObjFactory factory) {
this.factory = factory;
}
public void execute(){
//some code
// ......
// MyClass myClass = new MyClass(profile);
MyClass myClass = factory.create(profile);
myclass.someMethod();
}
}
so the unit test becomes simpler with only having to mock the Factory and have it return a mocked MyClass instance. Then it's simple to verify myclass.someMethod() was invoked as expected.
How to test a class which depends on Provider<>?
Please see the code below.
class ToTest {
#Inject
Provider<Processor> processorProvider;
public buildData() {
processorProvider.get().process();
}
class ProcessorProviderImpl implements Provider<Processor> {
#Inject
private Handler someHandler;
public Processor get() {
return new MyProcessor(somehandler)
}
}
public static class TestModule extends JukitoModule {
#Override
protected void configureTest() {
bind(Processor.class).toProvider(
ProcessorInstanceProviderImpl.class);
bindMock(SubHandler.class).in(TestSingleton.class);
}
}
class Handler {
#Inject
private SubHandler subHandler; // this is singleton instance
}
}
So when I mock subHandler it doesn't work and when I run unit test I am getting a NullPointerException where subHandler.handle() is getting called.
You can use Providers.of() to initialize processorProvider with a provider of your collaborator instance.
https://google.github.io/guice/api-docs/latest/javadoc/index.html?com/google/inject/util/Providers.html
test = new ToTest();
test.processorProvider = Providers.of(processorMock);
I have a class:
public abstract class Foo{
#Inject
private FooBarClient foobarclient;
public abstract long dofoo1();
public abstract long dofoo2();
public void doBar1(){
foobarClient.docall(faa);
}
}
I'd like to test the doBar1() method so I made my test class like this:
#RunWith(MockitoJUnitRunner.class)
public class FooTest {
private Foo foo;
#Mock
private FoobarClient foobarClient;
#Before
public void init() {
foo = new Foo() {
dofoo1(){};
};
}
#Test
public void testControleValiditeSite() throws Exception {
// G
Response response=....;
Mockito.when(foobarClient.docall(Mockito.any(faa.class))).thenReturn(
response);
// W
foo.doBar1();
// T;
}
But I got a null pointer exception on the fooBarclient in doBar1().
I also tried to mock the abstract with:
Foo foo = Mockito.mock(Foo,Mockito.CALLS_REAL_METHODS);
Is there a better method to do this test?
EDIT :
I used reflection. Now the code looks like:
#RunWith(MockitoJUnitRunner.class)
public class FooTest {
private Foo foo;
#Mock
private FoobarClient mockedFoobarClient;
#Before
public void init() {
foo = new Foo() {
dofoo1(){};
};
**MockitoAnnotations.initMocks(this);**
**ReflectionTestUtils.setField(foo , "foobarClient", mockedFoobarClient);**
}
#Test
public void testControleValiditeSite() throws Exception {
// G
Response response=....;
Mockito.when(foobarClient.docall(Mockito.any(faa.class))).thenReturn(
response);
// W
foo.doBar1();
// T;
}
You might not need to mock it, just create an instance in your test (assuming you're able to change the access type of client from private to protected).
Foo foo = new Foo() {
#Override
public long dofoo1() {
return 0;
}
#Override
public long dofoo2() {
return 0;
}
public void setClient(FooBarClient client) {
foobarclient = client;
}
};
foo.setClient(client);
foo.doBar1();
In your test class, create a non-abstract inner class that extends Foo. Use that in your test.
Is it possible to test the values of an instance passed as an argument to a method that is void using Mockito?
public String foo() {
Object o = new ObjectX();
o.setField("hi");
someDao.boo(o);
return "response";
}
boo is void and I want to test that foo sets the field to "hi"
Perhaps you would want to use doNothing method.
#Mock
SomeDao someDao;
#Captor
ArgumentCaptor<ObjectX> captor;
#Test
void test() {
doNothing().when(someDao).boo(captor.capture());
foo();
assertEquals("hi", captor.getValue().getField());
}
Updated
this is what JB in my comments is suggesting.
#RunWith(MockitoJUnitRunner.class)
public class BarTest
{
#Mock
private SomeDao someDao;
#InjectMocks
private Bar bar;
#Before
public void initMocks()
{
MockitoAnnotations.initMocks(this);
}
#Test
public void testFoo()
{
Mockito.doAnswer(new Answer<Object>()
{
#Override
public Object answer(InvocationOnMock invocation) throws Throwable
{
ObjectX x = (ObjectX) invocation.getArguments()[0];
Assert.assertEquals("hi", x.getField());
return null;
}
}).when(someDao).boo(Mockito.any(ObjectX.class));
Assert.assertEquals("response", bar.foo());
}
}
This below is my first answer and correct in its own way.
No it's not possible with Mockito, since ObjectX is a new Object within the void method, to accomplish this with Mockito then you would have to pass ObjectX in as an argument to the method foo(). You might want to look into Powermock if your code can't be changed.
public String foo(ObjectX objectX) {
Object o = objectX;
o.setField("hi");
someDao.boo(o);
return "response";
}
Test case
#Test
public void testFoo()
{
ObjectX mock = Mockito.mock(ObjectX.class);
Assert.assertEquals("response", foo(mock));
Mockito.verify(mock, Mockito.times(1)).setField(Mockito.eq("hi"));
}