If I have the following;
public class ClassA {
public void methodA(){
System.out.println("In ClassA, methodA");
}
}
public class ClassB {
public void methodB(){
}
}
and a junit test of;
#Test
public void testMocked(#Mocked final ClassB mockedB) {
System.out.println("Mocked inline");
new MockUp<ClassA>() {
#Mock
public void methodA() {
System.out.println("Inline mockup, mockedB:" + mockedB);
}
};
ClassA a = new ClassA();
a.methodA();
}
Then when I run the test I get;
Mocked inline
Inline mockup, mockedB:jmockitpractice.ClassB#329b0985
Which is as expected, the classB is Mocked, and an instance is available.
But, if I change this to create a helper class for mocking,
public class MockHelper {
#Mocked ClassB classB;
public void setupMocks(){
new MockUp<ClassA>() {
#Mock
public void methodA(){
System.out.println("In setupMocks, classB:"+classB);
}
};
}
}
and the junit becomes;
#Test
public void testMockedInClass() {
System.out.println("Mocked in helper class");
MockHelper mh = new MockHelper();
mh.setupMocks();
ClassA a = new ClassA();
a.methodA();
}
the result I get is;
Mocked in helper class
In setupMocks, classB:null
classB is not initialized by the #Mocked inside MockHelper
I would like to have all the mocking in a helper class, rather than having to declare all the mocking in the test class.
Any ideas why this doesn't work?
Thanks.
Thanks Dom Farr, the answer was inheritance.
public class MockHelper {
#Mocked
ClassB classB;
public void setupMocks() {
new MockUp<ClassA>() {
#Mock
public void methodA() {
System.out.println("In setupMocks, classB:" + classB);
}
};
}
}
and
public class mockTest extends MockHelper {
#Test
public void testMockedInClass() {
System.out.println("Mocked in helper class");
setupMocks();
ClassA a = new ClassA();
a.methodA();
}
}
As the test class extends the helper, it now works;
Mocked in helper class
In setupMocks, classB:jmockitpractice.ClassB#5d54e317
Related
I'm trying to mock a nested static class but getting a NullPointerException. Is there any way we can do this.
Sample code:
Parent Class
class Parent {
void record(String str) {
**//Getting a NPE at this line when running test case**
A.B.append(string);
}
}
Nested class
class A {
public static B b;
public static class B {
public void append(String str) {
//perform some task
}
}
}
Test class
#ExtendWith(MockitoExtension.class)
public class ParentTest {
#InjectMock
Parent parent;
#Test
public void dummy_test() {
A.B writer = mock(A.B.class);
doNothing().when(writer).append(any());
parent.record("Text");
}
}
#InjectMocks does not:
inject static fields.
inject fields to collaborating classes A
As your static field A.b is public, you can easily set it in a #BeforeEach method.
#ExtendWith(MockitoExtension.class)
public class ParentTest {
Parent parent = new Parent();
#Mock
A.B writer;
#BeforeEach
void setup() {
A.b = writer;
}
#Test
public void dummy_test() {
parent.record("Text");
}
}
I have the following scenario.
public class A {
//constructors
#Value(${useMethodA:false})
private boolean isUseMethodAEnabled;
public void func() {
if(isUseMethodAEnabled()) {
a();
} else {
b();
}
}
}
//methods a() and b()
public class B {
#Autowired
private A a;
public void funcPrincipal() {
A.a();
System.out.println("Method A.a() was called");
}
}
#RunWith(MockitoJUnitRunner.class)
public class BTest {
#InjectMocks
private B b;
#InjectMocks
#Spy
private A a = new A();
#Test
public void test() {
ReflectionTestUtils.setField(a, "isUseMethodAEnabled", true);
b.funcPrincipal();
// if A is annotated with #Spy -> the "isUseMethodAEnabled" is always false
}
}
See the above comment, please.
Is there any solution to change the "isUseMethodAEnabled" value from false to true using reflection?
If I switch to #Mock instead of #Spy everything works as expected. But for my test cases, I must use #Spy + #InjectMocks.
How can I use Mockito to check a call inside a method to another method of another class?
public class FirstClass {
private SecondClass secondClass = new SecondClass();
public void sum() {
secondClass.sum_2(1, 2);
}
}
I need to check that the second Class.sum_2() method is called with parameters
MyTest:
public class FirstTest {
FirstClass firstClass = new FirstClass();
SecondClass secondClass = Mockito.spy(SecondClass.class);
#Test
public void first() {
firstClass.sum();
Mockito.verify(secondClass).sum_2(eq(1), eq(2));
}
}
But answer:
Wanted but not invoked:
secondClass.sum_2(1, 2);
-> at FirstTest.first(FirstTest.java:14)
Actually, there were zero interactions with this mock.
There are a few possibilities how to solve this problem. As I mentioned in my comment, the most common approach is to create a constructor in FirstClass with a SecondClass parameter, so that you can inject an instance from outside.
Constructor injection
public class FirstClass {
private SecondClass secondClass;
public FirstClass(SecondClass secondClass) {
this.secondClass = secondClass;
}
public void sum() {
secondClass.sum_2(1, 2);
}
}
public class FirstTest {
FirstClass firstClass;
SecondClass secondClass;
#Before
public void setup() {
secondClass = Mockito.spy(new SecondClass());
firstClass = new FirstClass(secondClass);
}
#Test
public void first() {
firstClass.sum();
Mockito.verify(secondClass).sum_2(eq(1), eq(2));
}
}
If you can not create a constructor, you could add a setter and inject your instance that way.
Setter injection
public class FirstClass {
private SecondClass secondClass;
public void setSecondClass(SecondClass secondClass) {
this.secondClass = secondClass;
}
public void sum() {
secondClass.sum_2(1, 2);
}
}
public class FirstTest {
FirstClass firstClass;
SecondClass secondClass;
#Before
public void setup() {
secondClass = Mockito.spy(new SecondClass());
firstClass = new FirstClass();
firstClass.setSecondClass(secondClass);
}
#Test
public void first() {
firstClass.sum();
Mockito.verify(secondClass).sum_2(eq(1), eq(2));
}
}
And if you really, really can't modify FirstClass at all, you have to resort to using reflection.
With reflection
public class FirstClass {
private SecondClass secondClass;
public void sum() {
secondClass.sum_2(1, 2);
}
}
public class FirstTest {
FirstClass firstClass;
SecondClass secondClass;
#Before
public void setup() throws NoSuchFieldException, IllegalAccessException {
secondClass = Mockito.spy(new SecondClass());
firstClass = new FirstClass();
Field field = FirstClass.class.getDeclaredField("secondClass");
field.setAccessible(true);
field.set(firstClass, secondClass);
}
#Test
public void first() {
firstClass.sum();
Mockito.verify(secondClass).sum_2(eq(1), eq(2));
}
}
So my class is:
public final class MyClass {
private static MyObject myObject;
public static void setMyObject(MyObject myObject) {
MyClass.myObject = myObject;
}
private MyClass(MyObject myObject){
setMyObject(myObject);
}
public static Optional<Object2> getObject2(params) {
Optional<Object2> object2 = myObject.execute(params);
return object2;
}
I'm trying to test with Junit
#RunWith(MockitoJUnitRunner.class)
public class MyClassTest {
#Mock
private MyObject myObject;
private MyClass myClass;
#Before
public void initialize() {
MockitoAnnotations.initMocks(this);
}
#Test
public void test1() {
Mockito.doReturn(Optional.empty()).when(myObject).executeQueryWithArgument(any);
myclass = new Myclass(myObject);
}
}
myclass = new Myclass(myObject);
This line fails and says make MyClass constructor package private. Is there any way to do this without doing that?
Add mocked myObject to the MyClass using the set method and write the test, like this:
#RunWith(MockitoJUnitRunner.class)
public class MyClassTest {
#Mock
private MyObject myObject;
private MyClass myClass;
#Before
public void setUp() {
MyClass.setMyObject(myObject);
}
#Test
public void shouldDoSomething() {
// Arrange
Mockito.doReturn(Optional.empty()).when(myObject).executeQueryWithArgument(any);
// Act
Optional<Object2> actual = myClass.getObject2(.....);
// Assert
.....
}
}
I am writing unit tests for my akka actor classes. a field is being declared in abstract parent class and instantiated inside its constructor. During test case execution of child class that field is showing null. So how to instantiate the field from the test class.
Note: I am using partial Mocking also in testNG classes.
public abstract class ParentClass extends UntypedActor {
protected RestTemplate restTemplate;
protected ObjectMapper objMapper;
public ParentClass () {
super();
restTemplate = new RestTemplate();
objMapper = new ObjectMapper();
}
}
public class ChildClass extends ParentClass{
public ChildClass () {
super();
}
public void invoke(String json) throws Exception {
BeanClass bean = objMapper.readValue(json, Bean.class);
}
public String getJsonResponse(String json){
sysout("Get");
return "response";
}
}
public class ChildClassUnitTest {
#BeforeTest
public void setUp() throws Exception{
actorMock = PowerMock.createPartialMock(ChildClass.class,"getJsonResponse");
actorMock.getJsonResponse("req");
PowerMock.expectLastCall().andReturn("resp").anyTimes();
PowerMock.replay(actorMock);
}
#Test
public void testInvokePos() throws Exception{
ResponseClass response=actorMock.invoke("req");
System.out.println(response);
}
}
I am not known to json and I can only help with java code.
Please look at code below.
And my instance fields are initialized properly. They are not null. So I don't see any problem with your code atleast with what you have posted. Need to visit your UntypedActor class.
class ClassA
{
String x;
public ClassA ()
{
x = "Java";
}
}
abstract class ParentClass extends ClassA{
protected String restTemplate;
protected Integer objMapper;
public ParentClass () {
super();
restTemplate = " Language";
objMapper = 1;
}
}
class ChildClass extends ParentClass{
public ChildClass () {
super();
}
}
class HelloWorld
{
public static void main (String args[] )
{
ChildClass cc = new ChildClass ();
System.out.println ( cc.x + cc.restTemplate + cc.objMapper );
}
}
Output for the code is as expected
Java Language1