Java单元测试实践-07.Answer与未Stub的静态方法

news/2024/7/4 13:21:36

Java单元测试实践-00.目录(9万多字文档+700多测试示例)
https://blog.csdn.net/a82514921/article/details/107969340

1. Answer与未Stub的静态方法

以下主要说明,在对静态方法所在的类执行PowerMockito.mockStatic()方法时,指定的Answer对未被Stub的静态方法的影响。

Answer可以看作执行被Mock/Stub的方法时的回调处理。

2. 未Stub的方法的返回值

当静态方法所在的类通过PowerMockito.mockStatic()进行Mock,对于未被Stub的静态方法,默认情况下,返回值为返回类型对应的默认值。

参考“2. How about some stubbing?”( https://static.javadoc.io/org.mockito/mockito-core/latest/org/mockito/Mockito.html#stubbing )。默认情况下,对于所有有返回值的方法,Mock将根据情况返回null,原始/原始包装器值或空集合。例如,对于int/Integer返回0,对于boolean/Boolean返回false,对于String返回null等。

关于Java基本类型的默认值,可参考“Default Values”( https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html )。

未Stub的方法的各种返回类型对应的默认返回值如下所示:

类型默认返回值
Stringnull
StringBuffernull
StringBuildernull
byte0
Byte0
char‘\u0000’
Character0
booleanfalse
BooleanBoolean.False
short0
Short0
int0
Integer0
long0L
Long0L
float0F
Float0F
double0D
Double0D
BigDecimalnull
自定义类null
List元素数量为0的LinkedList对象
Map元素数量为0的HashMap对象

可参考示例TestStMockUnstubbedMethod类。

3. 被Stub方法条件不满足的返回值

对于被Stub的方法,在执行时若参数不满足Stub条件,返回值与未被Stub的方法相同,返回各类型对应的默认值。可参考示例TestStMockStubNotSatisfied类。

4. 未Stub的方法的返回值处理分析

对静态方法所在的类进行Mock时会使用PowerMockito.mockStatic()方法。

查看PowerMockito类的“public static synchronized void mockStatic(Class<?> type, Class<?>… types)”方法,注释为“为类的所有方法启用静态Mock”。在其中调用了“DefaultMockCreator.mock(type, true, false, null, null, (Method[]) null);”方法。

DefaultMockCreator类在org.powermock.api.mockito.internal.mockcreation包中,mock()方法中调用了“MOCK_CREATOR.createMock(type, isStatic, isSpy, delegator, mockSettings, methods);”。

MOCK_CREATOR为DefaultMockCreator类的对象,在DefaultMockCreator类的createMock()方法中,调用了“doCreateMock(type, isStatic, isSpy, delegatorCandidate, mockSettings, methods);”。

在DefaultMockCreator类的doCreateMock()方法中,调用了“createMethodInvocationControl(typeToMock, methods, delegator, mockSettings);”。

在DefaultMockCreator类的createMethodInvocationControl()方法中,调用了“Mockito.mock(type, mockSettings != null ? mockSettings : Mockito.withSettings());”,mockSettings对应PowerMockito.mockStatic()调用DefaultMockCreator.mock()方法时的第5个参数mockSettings,为null,因此调用上述Mockito.mock()方法时的参数为“type, Mockito.withSettings()”。

对应Mockito类的“public static <T> T mock(Class<T> classToMock, MockSettings mockSettings)”方法,调用了“MOCKITO_CORE.mock(classToMock, mockSettings);”,mockSettings参数对应Mockito.withSettings()。

在Mockito类的withSettings()方法中,返回“new MockSettingsImpl().defaultAnswer(RETURNS_DEFAULTS);”。

MockSettingsImpl类在org.mockito.internal.creation中,实现了org.mockito.MockSettings接口,defaultAnswer()方法的注释为“指定未被stub的方法调用的默认answer,传入的参数为未被stub的方法被设置的默认answer”。

RETURNS_DEFAULTS为Mockito类中的变量,等于Answers.RETURNS_DEFAULTS。

Answers枚举中的RETURNS_DEFAULTS值为GloballyConfiguredAnswer类的对象。

GloballyConfiguredAnswer类实现了Answer接口,answer()方法返回“new GlobalConfiguration().getDefaultAnswer().answer(invocation);”。

GlobalConfiguration类的getDefaultAnswer()方法返回“GLOBAL_CONFIGURATION.get().getDefaultAnswer();”,GLOBAL_CONFIGURATION为ThreadLocal<IMockitoConfiguration>,其值通过createConfig()方法设置。在createConfig()方法中,若new ClassPathLoader().loadConfiguration()返回非空则直接使用,若返回为空则使用DefaultMockitoConfiguration对象。

在ClassPathLoader类的loadConfiguration()方法中,判断是否已加载org.mockito.configuration.MockitoConfiguration类,若未加载则返回null,由于默认不存在该类,因此默认会返回null,GlobalConfiguration类的getDefaultAnswer()方法会返回DefaultMockitoConfiguration对象,

在DefaultMockitoConfiguration类的getDefaultAnswer()方法中,返回了ReturnsEmptyValues对象。

ReturnsEmptyValues类在org.mockito.internal.stubbing.defaultanswers包中,实现了Answer接口,在其answer()方法中,对toString与compareTo方法进行了单独处理,其他情况在returnValueFor方法中处理。

在ReturnsEmptyValues类的returnValueFor()方法中,通过Primitives.isPrimitiveOrWrapper()判断若为基本类型或其包装类型,则通过Primitives.defaultValue()方法返回对应的默认值。

Primitives类在org.mockito.internal.util包中,在其Map<Class<?>, Object> PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES变量中保存了基本类型及其包装类型,以及对应的默认值,代码如下:

PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(Boolean.class, false);
PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(Character.class, '\u0000');
PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(Byte.class, (byte) 0);
PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(Short.class, (short) 0);
PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(Integer.class, 0);
PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(Long.class, 0L);
PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(Float.class, 0F);
PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(Double.class, 0D);

PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(boolean.class, false);
PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(char.class, '\u0000');
PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(byte.class, (byte) 0);
PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(short.class, (short) 0);
PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(int.class, 0);
PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(long.class, 0L);
PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(float.class, 0F);
PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(double.class, 0D);

在ReturnsEmptyValues类的returnValueFor方法中,判断不是基本类型,也不是基本类型的包装类型时,处理代码如下:

if (type == Iterable.class) {
    return new ArrayList<Object>(0);
} else if (type == Collection.class) {
    return new LinkedList<Object>();
} else if (type == Set.class) {
    return new HashSet<Object>();
} else if (type == HashSet.class) {
    return new HashSet<Object>();
} else if (type == SortedSet.class) {
    return new TreeSet<Object>();
} else if (type == TreeSet.class) {
    return new TreeSet<Object>();
} else if (type == LinkedHashSet.class) {
    return new LinkedHashSet<Object>();
} else if (type == List.class) {
    return new LinkedList<Object>();
} else if (type == LinkedList.class) {
    return new LinkedList<Object>();
} else if (type == ArrayList.class) {
    return new ArrayList<Object>();
} else if (type == Map.class) {
    return new HashMap<Object, Object>();
} else if (type == HashMap.class) {
    return new HashMap<Object, Object>();
} else if (type == SortedMap.class) {
    return new TreeMap<Object, Object>();
} else if (type == TreeMap.class) {
    return new TreeMap<Object, Object>();
} else if (type == LinkedHashMap.class) {
    return new LinkedHashMap<Object, Object>();
} else if ("java.util.Optional".equals(type.getName())) {
    return JavaEightUtil.emptyOptional();
} else if ("java.util.OptionalDouble".equals(type.getName())) {
    return JavaEightUtil.emptyOptionalDouble();
} else if ("java.util.OptionalInt".equals(type.getName())) {
    return JavaEightUtil.emptyOptionalInt();
} else if ("java.util.OptionalLong".equals(type.getName())) {
    return JavaEightUtil.emptyOptionalLong();
} else if ("java.util.stream.Stream".equals(type.getName())) {
    return JavaEightUtil.emptyStream();
} else if ("java.util.stream.DoubleStream".equals(type.getName())) {
    return JavaEightUtil.emptyDoubleStream();
} else if ("java.util.stream.IntStream".equals(type.getName())) {
    return JavaEightUtil.emptyIntStream();
} else if ("java.util.stream.LongStream".equals(type.getName())) {
    return JavaEightUtil.emptyLongStream();
}

//Let's not care about the rest of collections.
return null;

总结如下:

使用PowerMockito.mockStatic()方法对类的静态方法进行Mock时,默认情况下会使用Mockito.RETURNS_DEFAULTS作为默认的Answer,对于未被Stub的方法,会返回各类型对应的默认值。

5. 对类进行Mock时设置默认Answer

PowerMockito.mockStatic()方法支持通过传入Answer或MockSettings对象设置默认的Answer,在执行被Mock类的未Stub的静态方法时,由指定的默认Answer进行处理。

当传入Answer对象时,对应PowerMockito类的方法“public static void mockStatic(Class<?> classMock, @SuppressWarnings(“rawtypes”) Answer defaultAnswer)”,示例如下:

PowerMockito.mockStatic(TestStaticPublicNonVoid2.class, new CallsRealMethods());

当传入MockSettings对象时,需要通过MockSettings defaultAnswer(Answer defaultAnswer)方法设置默认Answer,对应PowerMockito类的方法“public static void mockStatic(Class<?> classToMock, MockSettings mockSettings)”,示例如下:

PowerMockito.mockStatic(TestStaticPublicNonVoid2.class, Mockito.withSettings().defaultAnswer(new CallsRealMethods()));

当类的静态方法被Stub后,在执行该方法时受到对应的Stub控制,不再受默认Answer的影响,可参考示例TestStMockDftAnsCallsRealMethodsA1类。

5.1. 相关的类

5.1.1. Mockito类中的Answer实现类

Mockito类的成员变量包含一些Answer实现类,可作为默认Answer使用,如下所示:

  • RETURNS_DEFAULTS

参考 https://static.javadoc.io/org.mockito/mockito-core/latest/org/mockito/Mockito.html#RETURNS_DEFAULTS 。

对于方法未被Stub的被Mock的类,RETURNS_DEFAULTS是其默认的Answer。通常只返回一些空值。

该实现首先尝试使用全局配置,如果没有全局配置,则将使用返回0,空集合,null等值的默认Answer。

  • RETURNS_SMART_NULLS

参考 https://static.javadoc.io/org.mockito/mockito-core/latest/org/mockito/Mockito.html#RETURNS_SMART_NULLS 。

该实现在使用遗留代码时可能会有所帮助。未Stub的方法通常返回null。如果代码使用未stub调用返回的对象,可能会出现NullPointerException异常。该Answer实现返回SmartNull而不是null。SmartNull提供比NPE更好的异常消息,因为它指出了调用未Stub方法的代码行,只需单击堆栈跟踪就可以分析。

ReturnsSmartNulls首先尝试返回普通值( 0,空集合,空字符串等 ),然后尝试返回SmartNull。如果返回类型为final,则返回null。

ReturnSmartNulls可能会成为Mockito 4.0.0中的默认返回值策略。

  • RETURNS_MOCKS

参考 https://static.javadoc.io/org.mockito/mockito-core/latest/org/mockito/Mockito.html#RETURNS_MOCKS 。

该实现在使用遗留代码时可能会有所帮助。

ReturnMocks首先尝试返回普通值( 0,空集合,空字符串等 ),然后尝试返回Mock对象。如果返回值类型无法Mock( 如是final类型 ),则返回null。

  • RETURNS_DEEP_STUBS

参考 https://static.javadoc.io/org.mockito/mockito-core/latest/org/mockito/Mockito.html#RETURNS_DEEP_STUBS 。

常规干净的代码很少需要使用此功能,略。

  • CALLS_REAL_METHODS

参考 https://static.javadoc.io/org.mockito/mockito-core/latest/org/mockito/Mockito.html#CALLS_REAL_METHODS 。

该实现在使用遗留代码时可能会有所帮助。使用此实现时,未Stub的方法将委托给真实实现。这是一种创建部分模拟对象的方法,该对象默认情况下会调用真实方法。

  • RETURNS_SELF

参考 https://static.javadoc.io/org.mockito/mockito-core/latest/org/mockito/Mockito.html#RETURNS_SELF 。

每当调用返回等于类或超类的类型的方法时,都允许Mock构建器返回自身。

5.1.2. Answers枚举中的Answer实现类

Mockito类中的Answer实现类,均对应Answers枚举中的同名对象。

Answers枚举包含类型为Answer<Object>的变量implementation,对应Answer接口实现类,Answers枚举实现了Answer接口,在answer()方法中调用了implementation的answer()方法并返回,因此Answers的枚举值可以作为对应的Answer实现类使用,Answers枚举的枚举类型及枚举值对应的Answer实现类如下所示:

Answers枚举类型Answer实现类
RETURNS_DEFAULTSGloballyConfiguredAnswer
RETURNS_SMART_NULLSReturnsSmartNulls
RETURNS_MOCKSReturnsMocks
RETURNS_DEEP_STUBSReturnsDeepStubs
CALLS_REAL_METHODSCallsRealMethods
RETURNS_SELFTriesToReturnSelf

以上Answer实现类均在org.mockito.internal.stubbing.defaultanswers包中。

5.1.3. answers包中的Answer实现类

在org.mockito.internal.stubbing.answers包中存在一些Answer实现类,如下所示。

  • AnswersWithDelay

延迟指定的时间后,返回指定的Answer的返回值。

  • CallsRealMethods

该实现在使用遗留代码时可能会有所帮助。使用此实现时,未Stub的方法将委托给真实实现。这是一种创建部分模拟对象的方法,该对象默认情况下会调用真实方法。在调用真实方法时,通过InvocationOnMock invocation的callRealMethod()方法实现。

  • ClonesArguments

注释中说明为TODO,略。

  • DoesNothing

该实现什么也不做,在answer()方法中返回null。该实现不支持通过new创建实例,需要使用doesNothing()方法获得实例。

  • Returns

Returns类在构造时需要传入一个用户指定的对象Object value,在answer()方法中会返回value对象。

Mockito.when()方法的返回类型为OngoingStubbing接口,BaseStubbing类实现了OngoingStubbing接口。

在BaseStubbing类的thenReturn()方法中,返回“thenAnswer(new Returns(value));”,使用了Returns类。

  • ReturnsArgumentAt

返回传递参数中指定下标的参数值。argumentIndex表示调用的参数数组中的索引。如果此数字等于-1,则返回最后一个参数。

  • ReturnsElementsOf

返回集合的元素。永远返回最后一个元素。当需要返回元素集合时,该功能可能会很有用。

  • ThrowsException

总是抛出相同的Throwable对象的Answer实现类。

5.2. 执行真实方法

使用Mockito.CALLS_REAL_METHODS、Answers.CALLS_REAL_METHODS、CallsRealMethods等作为默认Answer,可以使被Mock的静态方法所在的类的未被Stub的方法默认执行真实方法。在调用PowerMockito.mockStatic()方法时,可以直接使用以上Answer,或使用Mockito.withSettings().defaultAnswer()获得默认Answer为以上指定Answer的MockSettings。

示例如下,可参考示例TestStMockDftAnsCallsRealMethodsA1、TestStMockDftAnsCallsRealMethodsA2、TestStMockDftAnsCallsRealMethodsA3、TestStMockDftAnsCallsRealMethodsWS1、TestStMockDftAnsCallsRealMethodsWS2、TestStMockDftAnsCallsRealMethodsWS3类。

PowerMockito.mockStatic(TestStaticPublicNonVoid2.class, Mockito.CALLS_REAL_METHODS);
PowerMockito.mockStatic(TestStaticPublicNonVoid2.class, Answers.CALLS_REAL_METHODS);
PowerMockito.mockStatic(TestStaticPublicNonVoid2.class, new CallsRealMethods());

PowerMockito.mockStatic(TestStaticPublicNonVoid2.class, Mockito.withSettings().defaultAnswer(Mockito.CALLS_REAL_METHODS));
PowerMockito.mockStatic(TestStaticPublicNonVoid2.class, Mockito.withSettings().defaultAnswer(Answers.CALLS_REAL_METHODS));
PowerMockito.mockStatic(TestStaticPublicNonVoid2.class, Mockito.withSettings().defaultAnswer(new CallsRealMethods()));

5.3. 抛出异常

使用ThrowsException作为默认Answer,可以使被Mock的静态方法所在的类的未被Stub的方法默认抛出指定异常,ThrowsException在创建时需要指定需要抛出的异常对象,如下所示,可参考示例TestStMockDftAnsThrowsExpt类。

PowerMockito.mockStatic(TestStaticPublicNonVoid2.class, new ThrowsException(new RuntimeException(TestConstants.MOCKED)));

5.4. 什么也不做

使用DoesNothing作为默认Answer,可以使被Mock的静态方法所在的类的未被Stub的方法什么也不做,DoesNothing需要使用doesNothing()方法返回对象实例,如下所示:

PowerMockito.mockStatic(TestStaticPublicNonVoid2.class, DoesNothing.doesNothing());

使用DoesNothing作为默认Answer,不同类型的返回值,除了数字相关基本类型返回0,boolean返回false外,其他类型均返回null,如下所示:

返回类型返回值
Stringnull
StringBuffernull
StringBuildernull
byte0
Bytenull
char‘\u0000’
Characternull
booleanfalse
Booleannull
short0
Shortnull
int0
Integernull
long0L
Longnull
float0F
Floatnull
double0D
Doublenull
BigDecimalnull
自定义类null
Listnull
Mapnull

可参考示例TestStMockDftAnsDoesNothing类。

6. Mockito.when()操作导致真实方法被执行或抛出异常

以下针对静态公有非void方法进行分析(对于静态方法,Mock.when().then…()不支持公有非void之外的方法)。

参考“CALLS_REAL_METHODS”( https://static.javadoc.io/org.mockito/mockito-core/latest/org/mockito/Mockito.html#CALLS_REAL_METHODS )。使用when(mock.getSomething()).thenReturn(fakeValue)语法进行Stub会执行真实方法,建议使用doReturn语法。

在对类执行PowerMockito.mockStatic()操作时,若默认Answer指定为执行真实方法,当使用Mockito.when().then…()方法执行Stub时,会执行真实方法。如以下示例中,执行Mockito.when(TestStaticPublicNonVoid2.testString())方法时,真实方法会执行,可参考示例TestStMockSECallsRealMethods类。

PowerMockito.mockStatic(TestStaticPublicNonVoid2.class, new CallsRealMethods());

Mockito.when(TestStaticPublicNonVoid2.testString(Mockito.anyString())).thenReturn(TestConstants.FLAG1);

在对类执行PowerMockito.mockStatic()操作时,若默认Answer指定为抛出异常,当使用Mockito.when().then…()方法执行Stub时,会抛出指定的异常。如以下示例中,执行Mockito.when(TestStaticPublicNonVoid2.testString())方法会抛出异常RuntimeException,可参考示例TestStMockSEThrowsExpt类。

PowerMockito.mockStatic(TestStaticPublicNonVoid2.class, new ThrowsException(new RuntimeException(TestConstants.MOCKED)));

Mockito.when(TestStaticPublicNonVoid2.testString(Mockito.anyString())).thenReturn(TestConstants.FLAG1);

6.1. Mockito.when()操作执行真实方法或抛出异常的原因分析

使用Mockito.when().then…()对静态公有非void方法进行Stub时,可以分解为以下三步:

  • 执行原始方法,参数使用Stub条件,获取返回值;

  • 针对返回值执行Mockito.when()方法,获得OngoingStubbing对象

  • 执行OngoingStubbing的then…()方法,设置Stub操作

例如对静态方法TestStaticPublicNonVoid2.testString()进行Stub,当参数为任意字符串时,返回字符串TestConstants.FLAG1对应的代码可以分解为以下步骤:

// 分解前
Mockito.when(TestStaticPublicNonVoid2.testString(Mockito.anyString())).thenReturn(TestConstants.FLAG1);

// 分解后

// 执行原始方法
String str = TestStaticPublicNonVoid2.testString(Mockito.anyString());

// 执行Mockito.when()方法,获得OngoingStubbing对象
OngoingStubbing ongoingStubbing = Mockito.when(str);

// 执行then...()方法,设置Stub操作
ongoingStubbing.thenReturn(TestConstants.FLAG2);

当执行PowerMockito.mockStatic方法指定默认Answer为执行真实方法时,以上执行原始方法的步骤会执行真实方法,可参考示例TestStMockSECallsRealMethods类;

当执行PowerMockito.mockStatic方法指定默认Answer抛出异常时,以上执行原始方法的步骤会抛出异常,可参考示例TestStMockSEThrowsExpt类;

当执行PowerMockito.mockStatic方法指定默认Answer为默认的返回空值的Answer时,以上执行原始方法的步骤不会执行真实方法,可参考示例TestStMockSEReturnsDefaults类;

当执行PowerMockito.mockStatic方法指定默认Answer什么也不做时,以上执行原始方法的步骤不会执行真实方法,可参考示例TestStMockSEDoesNothing类。

可以看到,Mockito.when()操作执行真实方法或抛出异常的原因,是Mockito.when()方法中指定的原始方法会被执行,有可能确实执行真实方法,或抛出异常。

6.2. 避免Stub操作执行真实方法或抛出异常

PowerMockito.do…().when()方法与Mockito.when().then…()方法功能类似,使用PowerMockito.do…().when()方法进行Stub时,不会执行真实方法,在有需要时可以使用PowerMockito.do…().when()方法替代Mockito.when().then…()方法进行Stub。

对静态方法使用PowerMockito.do…().when()方法进行Stub的语法为“PowerMockito.do…().when(静态方法所在的类.class, 静态方法名, Stub参数条件)”,示例如下:

PowerMockito.doReturn(TestConstants.MOCKED).when(TestStaticPublicNonVoid2.class, "testString", TestConstants.FLAG1);

Mockito.when().then…()方法及对应的PowerMockito.do…().when()方法如下所示:

then…()方法对应的do…()方法
Mockito.when().thenReturn()PowerMockito.doReturn().when()
Mockito.when().thenThrow()PowerMockito.doThrow().when()
Mockito.when().thenAnswer()PowerMockito.doAnswer().when()
Mockito.when().thenCallRealMethod()PowerMockito.doCallRealMethod().when()

可参考示例TestStMockSEThrowsExpt、TestStMockSECallsRealMethods类。

若使用PowerMockito.when(静态方法所在的类.class, 静态方法名, Stub参数条件).then…()方法进行Stub,无法避免执行真实方法或抛出异常,因为PowerMockito.when()方法中会调用“Mockito.when(Whitebox.<T>invokeMethod(clazz, methodToExpect, arguments))”,“Whitebox.<T>invokeMethod”方法会执行真实方法。


http://www.niftyadmin.cn/n/4057569.html

相关文章

歌词

我爸叫李刚 网络神曲的歌词&#xff1a;横行路中央&#xff0c;轿车轻飞扬。黄土地里养育着咱那霸道的爹娘。平凡的摸样&#xff0c;可咱爸是局长&#xff0c;只手遮天的大树&#xff0c;还有神秘的力量。我爸叫李刚&#xff0c;大名鼎鼎的李刚&#xff0c;李是李世民的李啊&am…

Java单元测试实践-09.Mockito的Stub参数条件

Java单元测试实践-00.目录&#xff08;9万多字文档700多测试示例&#xff09; https://blog.csdn.net/a82514921/article/details/107969340 1. Mockito的Stub参数条件 使用Mockito.when().then…()/Mockito.do…().when()等对方法进行Stub时&#xff0c;需要为每个参数指定S…

Java单元测试实践-10.Mock非静态方法

Java单元测试实践-00.目录&#xff08;9万多字文档700多测试示例&#xff09; https://blog.csdn.net/a82514921/article/details/107969340 1. Mock非静态方法 对非静态方法的进行Mock等处理时&#xff0c;部分情况与对Spring的Component组件的处理类似&#xff0c;主要在后…

Java单元测试实践-11.Mock后Stub Spring的@Component组件

Java单元测试实践-00.目录&#xff08;9万多字文档700多测试示例&#xff09; https://blog.csdn.net/a82514921/article/details/107969340 1. Spring Context加载次数 在使用PowerMock时&#xff0c;每执行一个测试类&#xff0c;Spring Context都会重新加载一次&#xff0…

Java单元测试实践-12.Answer与未Stub的Spring组件方法

Java单元测试实践-00.目录&#xff08;9万多字文档700多测试示例&#xff09; https://blog.csdn.net/a82514921/article/details/107969340 1. Answer与未Stub的Spring组件方法 1.1. 未Stub的方法的返回值 对于Spring的Component组件的Mock对象未Stub的方法&#xff0c;返回…

一本书,一个人

本文转自 http://smartcard.blog.com/tag/%E7%8E%8B%E7%88%B1%E8%8B%B1/ 国内的智能卡发展&#xff0c;可以上溯到上个世纪90年代初期。当时大家对于磁卡都知之甚少&#xff0c;更不要说IC卡、智能卡了。由于那段时间国际通用的智能卡标准还没有怎么得到很好地贯彻执行&#xf…

不受环境干扰,这套声学全息方案实现了虚实交互

一谈到全息显示&#xff0c;大家默认想到的就是光学全息方案&#xff0c;比如需要将光投射到某样东西上&#xff0c;比如视网膜&#xff0c;或是烟雾等介质上&#xff0c;才能成像。市面上一些常见的2D、3D全息方案&#xff0c;如全息风扇、Voxon全息系统等等&#xff0c;分别采…