mirror of
https://github.com/alibaba/testable-mock.git
synced 2025-02-13 13:20:32 +08:00
add test case for matchers
This commit is contained in:
parent
525e252f96
commit
43cd4aeeec
@ -0,0 +1,71 @@
|
||||
package com.alibaba.testable.demo.service;
|
||||
|
||||
|
||||
import com.alibaba.testable.demo.model.BlackBox;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author flin
|
||||
*/
|
||||
@Service
|
||||
public class DemoMatcherService {
|
||||
|
||||
/**
|
||||
* Method to be mocked
|
||||
*/
|
||||
private void methodToBeMocked() {
|
||||
// pretend to have some code here
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to be mocked
|
||||
*/
|
||||
private void methodToBeMocked(Object a1, Object a2) {
|
||||
// pretend to have some code here
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to be mocked
|
||||
*/
|
||||
private void methodToBeMocked(Object[] a) {
|
||||
// pretend to have some code here
|
||||
}
|
||||
|
||||
public void callMethodWithoutArgument() {
|
||||
methodToBeMocked();
|
||||
}
|
||||
|
||||
public void callMethodWithNumberArguments() {
|
||||
// named variable and lambda variable will be recorded as different type
|
||||
// should have them both in test case
|
||||
List<Float> floatList = new ArrayList<>();
|
||||
floatList.add(1.0F);
|
||||
floatList.add(2.0F);
|
||||
methodToBeMocked(1, 2);
|
||||
methodToBeMocked(1L, 2.0);
|
||||
Long[] longArray = new Long[]{1L, 2L};
|
||||
methodToBeMocked(new ArrayList<Integer>(){{ add(1); }}, new HashSet<Float>(){{ add(1.0F); }});
|
||||
methodToBeMocked(1.0, new HashMap<Integer, Float>(2){{ put(1, 1.0F); }});
|
||||
methodToBeMocked(floatList, floatList);
|
||||
methodToBeMocked(longArray);
|
||||
methodToBeMocked(new Double[]{1.0, 2.0});
|
||||
}
|
||||
|
||||
public void callMethodWithStringArgument() {
|
||||
methodToBeMocked("hello", "world");
|
||||
methodToBeMocked("testable", "mock");
|
||||
methodToBeMocked(new String[]{"demo"});
|
||||
}
|
||||
|
||||
public void callMethodWithObjectArgument() {
|
||||
methodToBeMocked(new BlackBox("hello"), new BlackBox("world"));
|
||||
methodToBeMocked(new BlackBox("demo"), null);
|
||||
methodToBeMocked(null, new BlackBox("demo"));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package com.alibaba.testable.demo.service;
|
||||
|
||||
import com.alibaba.testable.core.annotation.TestableMock;
|
||||
import com.alibaba.testable.demo.model.BlackBox;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static com.alibaba.testable.core.matcher.InvokeMatcher.*;
|
||||
import static com.alibaba.testable.core.tool.TestableTool.*;
|
||||
|
||||
|
||||
class DemoMatcherServiceTest {
|
||||
|
||||
private DemoMatcherService demo = new DemoMatcherService();
|
||||
|
||||
@TestableMock(targetMethod = "methodToBeMocked")
|
||||
private void methodWithoutArgument(DemoMatcherService self) {}
|
||||
|
||||
@TestableMock(targetMethod = "methodToBeMocked")
|
||||
private void methodWithArguments(DemoMatcherService self, Object a1, Object a2) {}
|
||||
|
||||
@TestableMock(targetMethod = "methodToBeMocked")
|
||||
private void methodWithArrayArgument(DemoMatcherService self, Object[] a) {}
|
||||
|
||||
@Test
|
||||
void should_match_no_argument() {
|
||||
demo.callMethodWithoutArgument();
|
||||
verify("methodWithoutArgument").withTimes(1);
|
||||
demo.callMethodWithoutArgument();
|
||||
verify("methodWithoutArgument").withTimes(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_match_number_arguments() {
|
||||
demo.callMethodWithNumberArguments();
|
||||
verify("methodWithArguments").without(anyString(), 2);
|
||||
verify("methodWithArguments").withInOrder(anyInt(), 2);
|
||||
verify("methodWithArguments").withInOrder(anyLong(), anyNumber());
|
||||
verify("methodWithArguments").with(1.0, anyMapOf(Integer.class, Float.class));
|
||||
verify("methodWithArguments").with(anyList(), anySetOf(Float.class));
|
||||
verify("methodWithArguments").with(anyList(), anyListOf(Float.class));
|
||||
verify("methodWithArrayArgument").with(anyArrayOf(Long.class));
|
||||
verify("methodWithArrayArgument").with(anyArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_match_string_arguments() {
|
||||
demo.callMethodWithStringArgument();
|
||||
verify("methodWithArguments").with(startsWith("he"), endsWith("ld"));
|
||||
verify("methodWithArguments").with(contains("stab"), matches("m.[cd]k"));
|
||||
verify("methodWithArrayArgument").with(anyArrayOf(String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_match_object_arguments() {
|
||||
demo.callMethodWithObjectArgument();
|
||||
verify("methodWithArguments").withInOrder(any(BlackBox.class), any(BlackBox.class));
|
||||
verify("methodWithArguments").withInOrder(nullable(BlackBox.class), nullable(BlackBox.class));
|
||||
verify("methodWithArguments").withInOrder(isNull(), notNull());
|
||||
}
|
||||
|
||||
}
|
@ -97,7 +97,7 @@ public class InvokeMatcher {
|
||||
}
|
||||
|
||||
public static InvokeMatcher anyListOf(final Class<?> clazz) {
|
||||
return anyClassWithTemplateOf(List.class, clazz);
|
||||
return anyClassWithCollectionOf(List.class, clazz);
|
||||
}
|
||||
|
||||
public static InvokeMatcher anySet() {
|
||||
@ -105,7 +105,7 @@ public class InvokeMatcher {
|
||||
}
|
||||
|
||||
public static InvokeMatcher anySetOf(final Class<?> clazz) {
|
||||
return anyClassWithTemplateOf(Set.class, clazz);
|
||||
return anyClassWithCollectionOf(Set.class, clazz);
|
||||
}
|
||||
|
||||
public static InvokeMatcher anyMap() {
|
||||
@ -113,16 +113,7 @@ public class InvokeMatcher {
|
||||
}
|
||||
|
||||
public static InvokeMatcher anyMapOf(final Class<?> keyClass, final Class<?> valueClass) {
|
||||
return any(new MatchFunction() {
|
||||
@Override
|
||||
public boolean check(Object value) {
|
||||
return value != null &&
|
||||
Map.class.isAssignableFrom(value.getClass()) &&
|
||||
value.getClass().getTypeParameters().length == 2 &&
|
||||
keyClass.isAssignableFrom(value.getClass().getTypeParameters()[0].getGenericDeclaration()) &&
|
||||
valueClass.isAssignableFrom(value.getClass().getTypeParameters()[1].getGenericDeclaration());
|
||||
}
|
||||
});
|
||||
return anyClassWithMapOf(keyClass, valueClass);
|
||||
}
|
||||
|
||||
public static InvokeMatcher anyCollection() {
|
||||
@ -130,7 +121,7 @@ public class InvokeMatcher {
|
||||
}
|
||||
|
||||
public static InvokeMatcher anyCollectionOf(final Class<?> clazz) {
|
||||
return anyClassWithTemplateOf(Collection.class, clazz);
|
||||
return anyClassWithCollectionOf(Collection.class, clazz);
|
||||
}
|
||||
|
||||
public static InvokeMatcher anyIterable() {
|
||||
@ -138,7 +129,7 @@ public class InvokeMatcher {
|
||||
}
|
||||
|
||||
public static InvokeMatcher anyIterableOf(final Class<?> clazz) {
|
||||
return anyClassWithTemplateOf(Iterable.class, clazz);
|
||||
return anyClassWithCollectionOf(Iterable.class, clazz);
|
||||
}
|
||||
|
||||
public static InvokeMatcher any(final Class<?> clazz) {
|
||||
@ -248,15 +239,53 @@ public class InvokeMatcher {
|
||||
});
|
||||
}
|
||||
|
||||
private static InvokeMatcher anyClassWithTemplateOf(final Class<?> collectionClass, final Class<?> clazz) {
|
||||
private static InvokeMatcher anyClassWithCollectionOf(final Class<?> collectionClass, final Class<?> clazz) {
|
||||
return any(new MatchFunction() {
|
||||
@Override
|
||||
public boolean check(Object value) {
|
||||
return value != null &&
|
||||
collectionClass.isAssignableFrom(value.getClass()) &&
|
||||
value.getClass().getTypeParameters().length == 1 &&
|
||||
clazz.isAssignableFrom(value.getClass().getTypeParameters()[0].getGenericDeclaration());
|
||||
allElementsHasType((Collection<?>)value, clazz);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static InvokeMatcher anyClassWithMapOf(final Class<?> keyClass, final Class<?> valueClass) {
|
||||
return any(new MatchFunction() {
|
||||
@Override
|
||||
public boolean check(Object value) {
|
||||
return value != null &&
|
||||
Map.class.isAssignableFrom(value.getClass()) &&
|
||||
allElementsHasType((Map<?, ?>)value, keyClass, valueClass);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Because of type erase, there's no way to directly fetch original type of collection template
|
||||
* this could be a temporary solution
|
||||
*/
|
||||
private static boolean allElementsHasType(Map<?, ?> items, Class<?> keyClass, Class<?> valueClass) {
|
||||
for (Map.Entry<?, ?> e : items.entrySet()) {
|
||||
if (!(keyClass.isAssignableFrom(e.getKey().getClass()) &&
|
||||
valueClass.isAssignableFrom(e.getValue().getClass()))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Because of type erase, there's no way to directly fetch original type of collection template
|
||||
* this could be a temporary solution
|
||||
*/
|
||||
private static boolean allElementsHasType(Collection<?> values, Class<?> clazz) {
|
||||
for (Object v : values.toArray()) {
|
||||
if (!clazz.isAssignableFrom(v.getClass())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user