EasyMock参数匹配器

时间:2020-02-23 14:41:17  来源:igfitidea点击:

EasyMock参数匹配器使我们可以在对方法进行存根时提供灵活的参数以进行匹配。
您将在EasyMock中找到许多any *()方法,这些方法可以与expect()一起使用,以提供方法调用的参数。

EasyMock参数匹配器示例

让我们看一个模拟ArrayList并为特定类型的任何参数添加其行为的简单示例。

package com.theitroad.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);
	}
}

注意,使用了" anyInt()"和" anyString()"来将参数指定为任何int或者字符串对象。

除了匹配任何参数之外,还有其他一些参数匹配器。
我们来看一些示例代码中的参数匹配器。

平等参量匹配器

我们可以使用same()参数匹配器方法来对同一个对象的行为进行存根。
如果要执行相等性检查,请使用eq()方法。

package com.theitroad.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();
	}
}

比较参数匹配器

我们可以使用lt(),gt(),leq()和geq()方法比较参数并返回特定的输出。
请注意,这些方法被重载以与原始数据类型和对象一起使用。
如果您将它们与任何对象一起使用,则它们应该是"可比较的"。

package com.theitroad.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<Integer> 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));

	}
}

条件参数匹配器

我们可以结合参数匹配器使用and()or()not()函数来编写更复杂的行为。

请注意,当我们使用参数匹配器对行为进行存根时,每个参数都必须是匹配器,否则,我们将收到一条错误消息。
因此,如果我们必须指定not(100),则将其写为not(eq(100))

这是一个使用条件参数匹配器的简单示例。

package com.theitroad.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));
	}
}

空参数匹配器

我们可以使用isNull()notNull()来匹配null和notnull参数。
但是,当我们使用其他参数匹配器时,isNull()会派上用场,并且不能直接使用null。

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参数的方法。
这些是:

  • startsWith(String)

  • EndsWith(String)

  • contains(String)

  • matchs(Regex):期望参数字符串与正则表达式匹配。

  • find(Regex):期望子字符串之一与正则表达式匹配。

这是一个简单的示例,显示了字符串参数匹配器的用法。

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("theitroad"));
//contains Pyt
assertTrue(mock.add("Python"));
//matches ads
assertTrue(mock.add("ads"));
//999 is one of substring
assertTrue(mock.add("ABC999DDD")); 

verify(mock);

自定义参数匹配器

尽管EasyMock参数匹配器支持广泛,但是如果您要实现自定义参数匹配器,则可以实现IArgumentMatcher接口并通过EasyMock.reportMatcher(IArgumentMatcher)使用它。