EasyMock Annotations – JUnit 4

Filed Under: EasyMock

EasyMock annotations can be used to create Mock objects. We can also tell the EasyMock framework to inject these mock objects into another concrete class.

EasyMock Annotations

There are two important EasyMock annotations that we should be aware of:

  1. @Mock: Used to specify a field to be mocked by EasyMock.
  2. @TestSubject: Used to specify an object where we want EasyMock to inject mocked objects created using @Mock annotation.

EasyMock Annotations Example

When we use EasyMock annotations, we have to explicitly initialize them through one of the following methods.

  1. @RunWith(EasyMockRunner.class): We can use this if we are using JUnit 4, note that JUnit 5 still doesn’t support this. If we use this with JUnit 5, then it will fallback to use JUnit 4 runner classes.
  2. org.easymock.EasyMockRule: This utilizes JUnit 4 Rule, so again it can’t be used with JUnit 5.
  3. EasyMockSupport.injectMocks(this): We can use this in @Before methods to tell EasyMock to inject mock objects. This is the preferred way for JUnit 5 and TestNG frameworks.

Let’s look at the example of using all the above-mentioned methods to create mock objects using EasyMock.

First of all, we will create some classes to mock. I will be using JUnit 4 for our example so that I can showcase all the three ways of creating mock objects through EasyMock annotations.


package com.journaldev.utils;

public interface IntegerUtils {

	int add(int x, int y);
}

package com.journaldev.utils;

public interface StringUtils {

	String reverse(String input);
	
	String convert(int i);
}

We will create mock objects of the above interfaces and inject them into the following concrete class.


package com.journaldev.utils;

public class MyUtils {

	private StringUtils su;
	private IntegerUtils iu;
	
	public MyUtils(StringUtils su, IntegerUtils iu) {
		this.su = su;
		this.iu = iu;
	}
	
	public int add(int i, int j) {
		return iu.add(i, j);
	}
	
	public String reverse(String s) {
		return su.reverse(s);
	}
	
	public String convert(int i) {
		return su.convert(i);
	}
}

EasyMockRunner

Here is the test class using @RunWith(EasyMockRunner.class) with EasyMock annotations.


package com.journaldev.easymock;

import static org.easymock.EasyMock.*;
import static org.junit.Assert.*;

import org.easymock.EasyMockRunner;
import org.easymock.Mock;
import org.easymock.TestSubject;
import org.junit.Test;
import org.junit.runner.RunWith;

import com.journaldev.utils.IntegerUtils;
import com.journaldev.utils.MyUtils;
import com.journaldev.utils.StringUtils;

@RunWith(EasyMockRunner.class)
public class EasyMockAnnotationsRunWithExample {

	@Mock StringUtils mockSU;
	@Mock IntegerUtils mockIU;

	@TestSubject MyUtils mu = new MyUtils(mockSU, mockIU);

	@Test
	public void test() {
		expect(mockIU.add(10, 10)).andReturn(20);
		expect(mockSU.convert(10)).andReturn("10");
		expect(mockSU.reverse("CAT")).andReturn("TAC");

		replay(mockSU, mockIU);

		assertEquals(20, mu.add(10, 10));
		assertEquals("10", mu.convert(10));
		assertEquals("TAC", mu.reverse("CAT"));
	}

}

Notice that behavior stubbing is done on the mocked objects. They are being called internally when we are invoking methods on the TestSubject object.

EasyMockRule

Here is the code snippet to use EasyMockRule. I have removed code from test method because they are same as earlier test method.


package com.journaldev.easymock;

import static org.easymock.EasyMock.*;
import static org.junit.Assert.*;

import org.easymock.EasyMockRule;
import org.easymock.Mock;
import org.easymock.TestSubject;
import org.junit.Rule;
import org.junit.Test;

import com.journaldev.utils.IntegerUtils;
import com.journaldev.utils.MyUtils;
import com.journaldev.utils.StringUtils;

public class EasyMockAnnotationsEasyMockRuleExample {

	@Mock StringUtils su;
	@Mock IntegerUtils iu;

	@TestSubject MyUtils mu = new MyUtils(su, iu);

	@Rule
	public EasyMockRule easyMockRule = new EasyMockRule(this);

	@Test
	public void test() {
	}

}

EasyMockSupport.injectMocks()


package com.journaldev.easymock;

import static org.easymock.EasyMock.*;
import static org.junit.Assert.*;

import org.easymock.EasyMockSupport;
import org.easymock.Mock;
import org.easymock.TestSubject;
import org.junit.Before;
import org.junit.Test;

import com.journaldev.utils.IntegerUtils;
import com.journaldev.utils.MyUtils;
import com.journaldev.utils.StringUtils;

public class EasyMockAnnotationsInjectExample {

	@Mock
	StringUtils su;
	@Mock
	IntegerUtils iu;

	@TestSubject
	MyUtils mu = new MyUtils(su, iu);

	@Before
	public void setup() {
		EasyMockSupport.injectMocks(this);
	}
	
	@Test
	public void test() {
	}

}

This way of creating mocks will work with JUnit 5 as well as TestNG testing framework.

Summary

EasyMock annotations allow us to create mocks at the global level, we can reuse these mocks in different test methods as well as inject them into various other objects dependent on them.

You can checkout complete code from our GitHub Repository.

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages