Reputation: 780
I have a question. There's a method with implementation using another objects. I'd like to test this method which will not using another objects invoking.
class Object1 {
public void method1() {
Object2 object2 = new Object2();
String info = object2.getInfo();
// ...
// working with info, which I want to test
// ...
}
}
class Object1Test {
@Test
public void testMethod1() {
Object1 object1 = new Object1();
object1.method(); // want to run this method without invoking Object2
}
}
Could you help me to understand how in junit while testing method1() can I mock the using of Object2 with something like Object2Mock?
Upvotes: 3
Views: 1439
Reputation: 5687
Dependency injection should be applied:
public class Object1 {
Object2 object2;
public Object1(Object2 object2) {
this.object2 = object2;
}
public void method1() {
String info = object2.getInfo();
}
}
and in test:
import org.junit.runner.RunWith;
import org.mockito.*;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import org.junit.*;
@RunWith(MockitoJUnitRunner.class)
public class Object1Test {
Object1 object1;
@Mock
Object2 mockedObject2;
@Before
public void setUp(){
object1 = new Object1(mockedObject2);
}
@Test
public void testMethod1() {
Mockito.when(mockedObject2.getInfo()).thenReturn("Mocked response");
object1.method1();
}
}
In code which you provided only PowerMockito is solution but it's strongly not recommended.
Upvotes: 0
Reputation: 10051
Unfortunately your code is not prepare for pure unit testing.
The reason is that Object1 is creating an instance of Object2. There is no way to easily mock a new statement.
I recommend you to use another approach (dependency injection, receive the object as a parameter or in the constructor).
If you can't change the relation between Object1 and Object2, you can use PowerMock.
Take a look at: https://github.com/jayway/powermock/wiki/MockConstructor
But take into account that PowerMock should be used only when there is no alternatives. The use of PowerMock denotes a bad design.
Upvotes: 1
Reputation: 3968
The issue is you are creating a new object within your method. You can refactor your code like this:
class Object1 {
public void method1() {
Object2 object2 = getObject2();
String info = object2.getInfo();
// ...
// working with info, which I want to test
// ...
}
public Object2 getObject2() {
return new Object2();
}
With the above code, now you can mock the method getObject2()
while testing method1()
.
Upvotes: 1
Reputation: 9648
You need to make some changes to your class to achieve what you are trying to do.
class Object1 {
private Object2 object2 = new Object2();
/* Setter Method for Object2 */
public void setObject2(Object2 object2) {
this.object2 = object2;
}
public void method1() {
String info = object2.getInfo();
// ...
// working with info, which I want to test
// ...
}
}
Now you just have to call your setter-method with the mocked object for Object2.
class Object1Test {
@Test
public void testMethod1() {
Object1 object1 = new Object1();
object1.setObject2(/* Pass your mocked object here */);
object1.method(); // want to run this method without invoking Object2
}
}
You can also use Mockito
or JMock
to create the object mocks. You can simply tell Mockito to return the dummy response whenever getInfo()
is invoked on Object2
. For example,
Mockito.when(mockedObject2.getInfo()).thenReturn("Dummy Response");
Upvotes: 1