前言
框架 | 用途和特点 | 缺点 |
JUnit | JUnit 是 Java 的单元测试框架,用于编写和执行测试用例 | 不直接支持模拟对象(Mocking),需要结合 Mockito 或其他 Mock 框架使用 |
Mockito | Mockito 是一个 Java Mock 框架,用于在单元测试中创建模拟对象
| 不支持模拟静态方法、私有方法和 final 类 |
PowerMockito | PowerMockito 是 Mockito 的扩展,提供了对 Mockito 无法模拟的类的模拟能力
| 学习曲线较陡峭 |
Spock | Spock 是基于 Groovy 的测试框架,适用于 Java 和 Groovy 应用的测试
|
|
Junit和Spock是测试框架,其关系就是LogBack与Log4fj的区别。
Mockito和PowerMockito是Mock框架,其不是测试框架,其需要结合Junit或Spock使用
一、简单场景
class SimpleTest extends spock.lang.Specification {def "测试加法运算"() {given:int num1 = 5int num2 = 3when:int result = num1 + num2then:result == 8}
}
二、Where 中添加多用例的场景
class WhereTest extends spock.lang.Specification {def "测试乘法运算结果"() {expect:num1 * num2 == expectedResultwhere:num1 | num2 | expectedResult2 | 3 | 64 | 5 | 206 | 7 | 42}
}
三、参数引用参数场景
class ParameterReferenceTest extends spock.lang.Specification {def "测试加法运算,结果与输入参数相关"() {expect:num1 + num2 == expectedSumwhere:num1 | num2 | expectedSum5 | 3 | num1 + num210 | 20 | num1 + num215 | 5 | num1 + num2}
}
四、Shared 对象场景
class SharedObjectTest extends spock.lang.Specification {@Shareddef sharedObject = new SharedObject()def "测试共享对象的属性"() {given:sharedObject.setValue(5)when:def retrievedValue = sharedObject.getValue()then:retrievedValue == 5}
}
五、Mock Final 类
import spock.mock.DetachedMockFactory
@RunWith(PowerMockRunner.class) // 必须
@PowerMockRunnerDelegate(Sputnik.class)
@PrepareForTest(FinalClass.class) // (1)必须将Final类WalletCoinDao添加到这里
class MockFinalClassTest extends spock.lang.Specification {@MockFinalClass finalClass@InjectMocksClassUnderTest classUnderTestdef "测试 Mock Final 类"() {given:when(finalClass.someMethod()).thenReturn("hello")when:def result = classUnderTest.invokeFinalClassMethod()then:result == "hello"}}
}final class FinalClass {public String someMethod() {return "Original Result";}
}
@Service
class ClassUnderTest {@Autowiredprivate FinalClass finalClass;public String invokeFinalClassMethod() {return finalClass.someMethod();}
}
六、Mock Final 方法
import spock.lang.Unroll
@RunWith(PowerMockRunner.class)
// 必须
@PowerMockRunnerDelegate(Sputnik.class)
@PrepareForTest([FinalClassMethod.class])class MockFinalMethodTest extends spock.lang.Specification {def "测试 Mock Final method "() {given:def finalClassMethod = PowerMockito.spy(new FinalClassMethod())PowerMockito.doReturn("hello1").when(finalClassMethod).someMethodV2()when:def result = finalClassMethod.someMethodV2()then:result == "hello1"}
}class SomeClass {final String finalMethod(int num) {"Original Result"}
}
七、Mock Static 方法
import spock.lang.Specification
import spock.mock.SharedMockFixture
import static org.mockito.Mockito.mockStatic
@RunWith(PowerMockRunner.class)
// 必须
@PowerMockRunnerDelegate(Sputnik.class)
@PrepareForTest([StaticClass.class])
class MockStaticMethodTest extends Specification implements SharedMockFixture {def "测试 Mock Static 方法"() {given:PowerMockito.mockStatic(StaticClass.class)when:PowerMockito.when(StaticClass.staticMethod()).thenReturn("Expected Result")then:new ClassUnderTest().invokeStaticMethod2() == "Expected Result"}
}class StaticClass {static String staticMethod() {return "Original Static Result";}
}
八、Mock 私有变量
import spock.lang.Specification
import org.spockframework.util.InternalSpockErrorclass MockPrivateVariableTest extends Specification {def "测试 Mock 私有变量"() {given:def target = new TargetClass()def field = TargetClass.getDeclaredField("privateVariable")field.setAccessible(true)field.set(target, "Mocked Value")when:def result = target.accessPrivateVariable()then:result == "Expected Result"}
}class TargetClass {private String privateVariable = "Original Value"String accessPrivateVariable() {privateVariable}
}
九、Mock 无返回值的函数
import spock.lang.Specificationclass MockVoidMethodTest extends Specification {def "测试 Mock 无返回值的函数"() {//givendoNothing().when(myclass).doSayHello(Mockito.anyString());//whenString result = myclass.sayHello("hello");//thenassertEquals("ok", result);}
}class SomeObject {void voidMethod() {// 原始实现}
}
十、Mock 抛异常
import spock.lang.Specificationclass MockExceptionTest extends Specification {def "测试 Mock 抛异常"() {//givendoThrow(new RuntimeException("my exception")).when(myclass).doSayHello(Mockito.anyString());//whenString result = myclass.sayHello("hello");//thenassertEquals("ok", result);}
}class SomeObject {void methodThatThrows() {// 原始实现}
}