EasyMock Argument Matchers

Filed Under: EasyMock

EasyMock argument matchers allow us to provide the flexible argument for matching when stubbing the methods. You will find a lot of any*() methods in EasyMock that can be used with expect() to provide arguments for a method call.

EasyMock Argument Matchers Example

Let’s look at a simple example of mocking ArrayList and stubbing its behaviors for any argument of a specific type.


package com.journaldev.easymock;

import static org.easymock.EasyMock.*;
import static org.junit.jupiter.api.Assertions.*;

import java.util.ArrayList;

import org.junit.jupiter.api.Test;

public class EasyMockAgrumentMatcherExample {

	@Test
	public void test() {
		ArrayList<Object> mockList = mock(ArrayList.class);
		expect(mockList.add(anyInt())).andReturn(true);
		expect(mockList.add(anyString())).andReturn(false);
		replay(mockList);

		assertTrue(mockList.add(10));
		assertFalse(mockList.add("Hi"));
		
		verify(mockList);
	}
}

Notice the use of anyInt() and anyString() for specifying the argument as any int or string object.

Apart from matching any argument, there are some other argument matchers too. Let’s look at some of these argument matchers with example code.

Equality Argument Matcher

We can use same() argument matcher method for stubbing behavior with same object. If you want to perform equality check, use eq() method.


package com.journaldev.easymock;

import static org.easymock.EasyMock.*;
import static org.junit.jupiter.api.Assertions.*;

import java.util.ArrayList;

import org.junit.jupiter.api.Test;

public class EasyMockAgrumentMatcherEqualityExample {

	@Test
	public void test() {
		Utils mock = mock(Utils.class);
		Object obj = new Object();
		
		expect(mock.convert(same(obj))).andReturn("True");
		expect(mock.convert(eq("ABC"))).andReturn("Awesome");

		expect(mock.convert(anyObject())).andReturn("False");
		replay(mock);
		
		assertEquals("True", mock.convert(obj));
		assertEquals("Awesome", mock.convert("ABC"));

		assertEquals("False", mock.convert(new Object()));
	}
}

class Utils {
	public String convert(Object obj) {
		return obj.toString();
	}
}

Comparison Argument Matcher

We can use lt(), gt(), leq() and geq() methods to compare arguments and return specific output. Note that these methods are overloaded to use with primitive data types as well as objects. If you are using them with any Object, then they should be Comparable.


package com.journaldev.easymock;

import static org.easymock.EasyMock.*;
import static org.junit.jupiter.api.Assertions.*;

import java.util.ArrayList;
import java.util.List;

import org.junit.jupiter.api.Test;

public class EasyMockAgrumentMatcherComparisonExample {

	@Test
	public void test() {
		List mock = mock(ArrayList.class);
		
		expect(mock.add(lt(10))).andReturn(true);
		expect(mock.add(geq(10))).andReturn(false);
		replay(mock);
		
		assertTrue(mock.add(5));
		assertFalse(mock.add(100));

	}
}

Conditional Argument Matchers

We can use and(), or() and not() functions with argument matchers to write more complex behaviors.

Note that when we are using argument matchers to stub behaviors, every argument has to be a matcher otherwise, we will get an error message. So if we have to specify not(100), then write it as not(eq(100)).

Here is a simple example of using conditional argument matchers.


package com.journaldev.easymock;

import static org.easymock.EasyMock.*;
import static org.junit.jupiter.api.Assertions.*;

import java.util.ArrayList;
import java.util.List;

import org.junit.jupiter.api.Test;

public class EasyMockAgrumentMatcherConditionalExample {

	@Test
	public void test() {
		List<Integer> mock = mock(ArrayList.class);
		
		//return true if number is between 0 to 10
		expect(mock.add(and(gt(0), lt(10)))).andReturn(true);
		
		//return true if number is 33 or 77
		expect(mock.add(or(eq(33), eq(77)))).andReturn(true);
		
		//return true if number is not 99
		expect(mock.add(not(lt(100)))).andReturn(false);		
				
		replay(mock);
		
		assertTrue(mock.add(5));
		assertTrue(mock.add(33));
		assertFalse(mock.add(102));
	}
}

Null Argument Matchers

We can use isNull() and notNull() to match null and not-null arguments. However, isNull() comes handy when we are using other argument matchers and can’t use null directly.


List<Object> mock = mock(ArrayList.class);

expect(mock.add(isNull())).andReturn(true);
expect(mock.add(notNull())).andReturn(false);
replay(mock);

assertTrue(mock.add(null));
assertFalse(mock.add("Hi"));

String Argument Matchers

There are few utility methods especially for matching String arguments. These are:

  • startsWith(String)
  • endsWith(String)
  • contains(String)
  • matches(Regex): Expects argument string to match the regex.
  • find(Regex): Expects one of the substring to match the regex.

Here is a simple example showing usage of string argument matchers.


List<String> mock = mock(ArrayList.class);

expect(mock.add(startsWith("Java"))).andReturn(true);
expect(mock.add(endsWith("Dev"))).andReturn(true);
expect(mock.add(contains("Pyt"))).andReturn(true);
expect(mock.add(matches("^[abc]d."))).andReturn(true);
expect(mock.add(find("[9]{3}"))).andReturn(true);

replay(mock);

//startsWith Java
assertTrue(mock.add("Java World"));
//endsWith Dev
assertTrue(mock.add("JournalDev"));
//contains Pyt
assertTrue(mock.add("Python"));
//matches ads
assertTrue(mock.add("ads"));
// 999 is one of substring
assertTrue(mock.add("ABC999DDD")); 

verify(mock);

Custom Argument Matcher

Although EasyMock argument matchers support is extensive, if you want to implement a custom argument matcher then you can implement IArgumentMatcher interface and use it through EasyMock.reportMatcher(IArgumentMatcher).

You can checkout complete project and more EasyMock examples 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