网站开发公司需要哪些部门,wordpress怎么添加目录,无锡大型设计网站报价,企业网站怎么做中英文切换这里写目录标题 第一章、模拟对象1.1#xff09;①mock()方法#xff1a;1.2#xff09;②spy()方法#xff1a; 第二章、模拟对象行为2.1#xff09;模拟方法调用①when()方法 2.2#xff09;模拟返回值②thenReturn(要返回的值)③doReturn() 2.3#xff09;模拟并替换… 这里写目录标题 第一章、模拟对象1.1①mock()方法1.2②spy()方法 第二章、模拟对象行为2.1模拟方法调用①when()方法 2.2模拟返回值②thenReturn(要返回的值)③doReturn() 2.3模拟并替换原方法的行为④thenAnswer()⑤doAnswer 2.4部分模拟时是否调用真实方法⑥thenCallRealMethod()⑦doCallRealMethod() 2.5模拟抛出异常⑧thenThrow()⑨doThrow() 2.6模拟构造函数和静态方法⑩模拟构造函数MockedConstruction⑩①模拟静态方法MockedStatic 2.7其他方法使void方法什么也不做doNothing()重置模拟对象状态reset()方法 第三章、模拟对象行为验证3.1验证调用次数①verify()方法②verify(object, Mockito.times(2))方法 3.2验证是否发生交互③verifyNoMoreInteractions()方法④verifyZeroInteractions()方法 第四章、Assert结果断言4.1验证结果①验证是否相等Equals②验证结果真假③验证结果是否为null④验证对象引用⑤验证是否满足指定条件 4.2使结果直接失败⑥使测试用例失败fail() 第一章、模拟对象
1.1①mock()方法
用于创建给定类或接口的模拟对象创建对象的另一种方式就是直接用Mock/InjectMocks注解来创建模拟对象第三章有介绍。
注意无法mock final类和final方法静态方法和静态对象私有方法。
import java.util.List;
import static org.mockito.Mockito.*;public class MockitoMockMethodExample {public void testMultipleMocks() {// 使用 Mockito.mock() 方法创建多个模拟对象ListString mockList1 mock(List.class);ListString mockList2 mock(List.class);// 设置第一个模拟对象的预期行为when(mockList1.size()).thenReturn(5);// 设置第二个模拟对象的预期行为when(mockList2.size()).thenReturn(10);// 断言模拟对象的行为符合预期assert(mockList1.size() 5);assert(mockList2.size() 10);}
}1.2②spy()方法
用于部分模拟对象可以对真实对象的特定方法进行覆盖。它保留了真实对象的部分行为。Spy对象既可以模拟方法的返回值也可以保留方法的实际行为。
示例中spy() 方法创建了一个 ArrayList 对象的部分模拟然后使用 when().thenReturn() 方法对 size() 方法进行了模拟。最后调用部分模拟对象的真实方法时模拟的方法返回了预期的值。
import static org.mockito.Mockito.*;// 示例创建一个部分模拟的对象
ListString list new ArrayList();
ListString listSpy spy(list);// 示例模拟部分方法
when(listSpy.size()).thenReturn(10);// 示例调用部分模拟对象的真实方法
listSpy.add(one);
System.out.println(listSpy.size()); // 输出 10因为 size() 方法被模拟为返回 10第二章、模拟对象行为
2.1模拟方法调用
①when()方法
用于指定模拟对象的方法调用并设置相应的操作例如返回值、异常等。 when()此方法需要一个方法调用作为参数通常是模拟对象的一个方法。它会记录下这个方法调用并允许你接下来定义这个方法调用的行为。
when(service.方法名(参数))2.2模拟返回值
②thenReturn(要返回的值)
thenReturn(T value)这个方法需要你想要返回的值作为参数。当 when() 中指定的方法被调用时模拟对象将返回这个值。
当使用模拟对象(用Mock注释)选择thenReturn模拟有返回值非void的方法
如果使用监视对象(用Spy注释)when(…) thenReturn(…)在返回指定值之前会进行实际方法调用。就需要处理这个方法可能抛出的异常。所以有异常的方法一般不使用thenReturn
when(service.方法名(参数)).thenReturn(要返回的值)示例
public class MockitoExample {Testvoid testWhenThenReturn() {// 创建模拟对象List mockedList Mockito.mock(List.class);// 定义当调用mockedList.get(0)时返回firstMockito.when(mockedList.get(0)).thenReturn(first);// 使用模拟对象System.out.println(mockedList.get(0)); // 输出 firstSystem.out.println(mockedList.get(1)); // 输出 null因为我们没有定义get(1)的行为}
}
③doReturn()
当使用模拟对象(用Mock注释)选择thenReturn模拟无返回值void的方法
如果使用监视对象(用Spy注释)doReturn(…) when(…)不会真正调用该方法。这意味着即使被调用的真实方法抛出异常也不会影响测试。所以doReturn() 方法通常用于对部分模拟对象spy进行方法模。
doReturn(10).when(listSpy).size();示例
import static org.mockito.Mockito.*;// 示例创建一个部分模拟的对象
ListString list new ArrayList();
ListString listSpy spy(list);// 示例使用doReturn方法模拟部分方法
doReturn(10).when(listSpy).size();// 示例调用部分模拟对象的真实方法
listSpy.add(one);
System.out.println(listSpy.size()); // 输出 10因为 size() 方法被模拟为返回 102.3模拟并替换原方法的行为
④thenAnswer()
如果在方法调用中需要固定的返回值则应使用thenReturn()。 如果需要执行某些操作或替换原方法的行为则应使用thenAnswer()
如下示例在调用getCurrentTime方法时作用是获取当前的日期和时间。我想使用Instant.now().toEpochMilli();方法替换getCurrentTime方法的内部代码逻辑。
则需要先 1、实现接口org.mockito.stubbing.Answer的类的对象。 2、在方法answer…内部自定义行为。 3、我们从模拟对象中调用模拟方法getCurrentTime时实际上是执行answer中的代码逻辑。
import org.junit.Test;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.time.Instant;public class TimeServiceTest {Testpublic void testGetCurrentTime() {// 创建TimeService类的模拟对象TimeService timeService Mockito.mock(TimeService.class);// 创建一个 Answer 对象实现 answer 方法来返回当前系统时间AnswerLong answer new AnswerLong() {public Long answer(InvocationOnMock invocation) throws Throwable {return Instant.now().toEpochMilli();}};// 使用 thenAnswer() 指定模拟对象的方法返回当前系统时间
Mockito.when(timeService.getCurrentTime()).thenAnswer(answer);// 调用模拟对象的方法实际执行的是answer中的代码逻辑long currentTime timeService.getCurrentTime();// 验证方法是否被调用Mockito.verify(timeService).getCurrentTime();// 进行进一步的断言}
}我们可以也使用Java 8 lambda功能来实现answer方法。
public class TimeServiceTest {Testpublic void testGetCurrentTime() {// 创建TimeService类的模拟对象TimeService timeService Mockito.mock(TimeService.class);// 创建一个 Answer 对象实现 answer 方法来返回当前系统时间AnswerLong answer new AnswerLong() {public Long answer(InvocationOnMock invocation) throws Throwable {return Instant.now().toEpochMilli();}};// 使用 thenAnswer() 指定模拟对象的方法返回当前系统时间Mockito.when(timeService.getCurrentTime()).thenAnswer(answer);// 调用模拟对象的方法实际执行的是answer中的代码逻辑long currentTime timeService.getCurrentTime();// 验证方法是否被调用Mockito.verify(timeService).getCurrentTime();// 进行进一步的断言}
}⑤doAnswer
更适用于对 void 方法进行模拟。你可以使用 doAnswer 来执行额外的操作比如触发回调、记录日志等因为 void 方法本身没有返回值。 创建一个 Answer 对象实现 answer 方法来指定特定的操作或返回值
示例中通过Mockito的模拟我们成功地替换了原来calculate方法的实际行为
doAnswer(answer).when(service).方法(Mockito.anyInt(), Mockito.anyInt());示例
// 假设有一个名为Service的类其中包含一个方法
public class Service {public int calculate(int a, int b) {// 一些复杂的计算return a b;}
}// 在测试中使用Mockito来模拟Service类的行为
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;public class ServiceTest {Testpublic void testCalculate() {// 创建Service类的模拟对象Service service Mockito.mock(Service.class);// 创建一个 Answer 对象实现 answer 方法来指定特定的操作或返回值AnswerInteger answer new AnswerInteger() {public Integer answer(InvocationOnMock invocation) throws Throwable {int a invocation.getArgument(0);int b invocation.getArgument(1);// 在 answer 方法中执行特定的操作或返回特定的值return a * b;}};//doAnswer表示当calculate方法被调用时执行特定的操作
Mockito.doAnswer(answer).when(service).calculate(Mockito.anyInt(), Mockito.anyInt());// 调用模拟对象的方法//当调用service.calculate(2, 3)时实际执行的是2 * 3结果为6int result service.calculate(2, 3);// 验证方法是否被调用并且返回了预期的值Mockito.verify(service).calculate(2, 3);assertEquals(6, result);}
}2.4部分模拟时是否调用真实方法
⑥thenCallRealMethod()
用于部分模拟对象spy时当调用指定方法时实际调用对象的真实方法而不是模拟方法。特别是当需要部分模拟对象并且希望某些方法执行真实逻辑时。
when(service.方法名(参数)).thenCallRealMethod()示例
// 假设有一个名为UserService的类
public class UserService {public String process(String input) {// 实际的方法逻辑return Processed: input;}
}// 创建UserService的部分模拟对象
UserService userService Mockito.spy(UserService.class);// 当调用process方法时执行实际的方法逻辑
Mockito.when(userService.process(input)).thenCallRealMethod();// 调用部分模拟对象的方法
String result userService.process(input);// 输出结果将会是Processed: input因为实际的方法逻辑被执行了
System.out.println(result);⑦doCallRealMethod()
用于部分模拟对象spy时用于调用真实对象的实际方法而不是模拟方法的行为。这在部分模拟对象spy中特别有用因为它允许部分模拟对象调用其真实的方法而不是模拟方法的行为。
doCallRealMethod().when(someObject).someMethod();示例
// 创建一个部分模拟对象
SomeClass someObject mock(SomeClass.class);
doCallRealMethod().when(someObject).someMethod();// 调用真实方法
someObject.someMethod();2.5模拟抛出异常
⑧thenThrow()
thenThrow 适用于有出参的方法thenThrow方法指定了在调用该方法时抛出指定的异常而 thenThrow() 方法更适合在特定条件下抛出异常。
when(mockedList.get(0)).thenThrow(new RuntimeException())示例这里是RuntimeException
when(service.方法名(参数)).thenThrow(new RuntimeException());示例
import static org.mockito.Mockito.*;public class ExampleTest {Testpublic void testMethod() {// 创建被mock的对象SomeClass mockObj mock(SomeClass.class);// 设置当调用mockObj.method时抛出异常when(mockObj.method(anyString())).thenThrow(new RuntimeException(Something went wrong));// 调用被mock的方法这里会抛出异常mockObj.method(test);}
}⑨doThrow()
doThrow 适用于 没有出参的方法在测试中模拟抛出异常的情况。doThrow() 方法更适合在调用特定方法时强制抛出异常
doThrow(new RuntimeException()).when(mockedList).get(0)示例
import static org.mockito.Mockito.*;// 创建mock对象
ListString mockedList mock(List.class);// 指定当调用mockedList的get()方法时抛出异常
doThrow(new RuntimeException()).when(mockedList).get(0);// 调用被测方法
mockedList.get(0); // 这里会抛出指定的异常2.6模拟构造函数和静态方法
⑩模拟构造函数MockedConstruction
在单元测试中当需要在测试中模拟某个类的实例时使用MockedConstruction可以模拟构造函数的行为如果没有模拟构造函数那么在使用new关键字创建对象时会执行实际的构造函数
作用当需要在测试中模拟第三方库的对象时可以使用MockedConstruction来模拟构造函数而不实际调用第三方库的构造函数从而避免对外部资源的依赖。
import org.junit.jupiter.api.Test;
import org.mockito.MockedConstruction;
import org.mockito.Mockito;public class ExampleTest {Testvoid testWithMockedConstruction() {//模拟构造函数行为try (MockedConstructionMyClass mocked Mockito.mockConstruction(MyClass.class)) {//模拟完以后再创建对象此时执行的就是模拟的构造函数而不是实际的MyClass myClass new MyClass();//调用get方法Mockito.when(myClass.getName()).thenReturn(mocked value);// 在这里使用myClass进行测试}}
}⑩①模拟静态方法MockedStatic
MockedStatic是Mockito框架中的一个类用于模拟静态方法的行为。通过使用MockedStatic您可以模拟静态方法的返回值以及验证静态方法的调用次数。
import org.mockito.MockedStatic;
import org.mockito.Mockito;public class Example {public void exampleMethod() {//YourClassWithStaticMethod是包含静态方法的类
try (MockedStaticYourClassWithStaticMethod mockedStatic Mockito.mockStatic(YourClassWithStaticMethod.class)) {mockedStatic.when(YourClassWithStaticMethod::staticMethod(param1)).thenReturn(someValue);// 调用静态方法
YourClassWithStaticMethod.staticMethod(param1);// 验证静态方法是否被调用过
mockedStatic.verify(YourClassWithStaticMethod::staticMethod(param1));}}
}2.7其他方法
使void方法什么也不做doNothing()
doNothing() 方法的作用是用于设置模拟对象的 void 方法不执行任何操作。因为 mock 对象中void 函数就是什么都不做所以该方法更适合 spy 对象。
Mockito.doNothing().when(service).方法名(参数)示例1
static class ExampleClass {public void hello() {System.out.println(吃过了);}}
/
public class MockDemo {Testpublic void test() {ExampleClass exampleClass spy(new ExampleClass ());ExampleClass .hello(); //打印吃过了// 通过doNothein让方法什么都不做doNothing().when(exampleClass ).hello();exampleClass.hello(); // 什么都不输出}
}
示例2这是复制的国外一个博主的代码
List list new LinkedList();
List spy spy(list);
//lets make clear() do nothing
doNothing().when(spy).clear();
spy.add(one);
//clear() does nothing, so the list still contains one
spy.clear();重置模拟对象状态reset()方法
用于重置模拟对象的状态或者将对象恢复到初始状态
import org.junit.Test;
import org.mockito.Mockito;// 创建一个模拟对象
ListString mockedList Mockito.mock(List.class);// 对模拟对象进行方法调用
mockedList.add(one);
System.out.println(mockedList.size()); // 输出 1// 重置模拟对象的状态
Mockito.reset(mockedList);// 再次对模拟对象进行方法调用
System.out.println(mockedList.size()); // 输出 0因为模拟对象的状态已被重置第三章、模拟对象行为验证
3.1验证调用次数
①verify()方法
用于验证模拟对象的指定方法是否被调用。可以进一步验证方法的调用次数和参数。
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;import java.util.List;public class MockitoExample {Testvoid testMock() {// 创建模拟对象List mockedList Mockito.mock(List.class);// 使用模拟对象mockedList.add(one);Mockito.verify(mockedList).add(one);// 验证模拟对象的某些行为是否发生过Mockito.verify(mockedList, Mockito.times(1)).add(one);}
}
②verify(object, Mockito.times(2))方法
是一个 Mockito 框架中的验证方法用于验证某个行为在模拟对象上被调用了几次。times() 方法需要一个整数参数代表你期望的调用次数。然后将返回一个 VerificationMode 实例这个实例可以和 verify() 方法一起使用来检查某个操作是否被执行了指定次数。
下述代码Mockito.times(2) 指的是我们期望 add() 方法在模拟对象 mockedList 上被调用了两次。如果 add() 方法的实际调用次数不匹配我们的期望例如它只被调用了一次或者三次那么代码会抛出一个 MockitoAssertionError 异常。
public class MockitoExample {Testvoid testTimes() {// 创建模拟对象List mockedList Mockito.mock(List.class);// 模拟方法调用mockedList.add(one);mockedList.add(one);// 验证该方法是否被调用了两次Mockito.verify(mockedList, Mockito.times(2)).add(one);}
}
下述代码不会抛出异常因为add了两次与预期相符
import java.util.List;
import static org.mockito.Mockito.*;public class MockitoTimesExample {public void testMethodInvocation() {// 创建模拟对象ListString mockList mock(List.class);// 调用模拟对象的方法mockList.add(item1);mockList.add(item2);// 验证方法调用次数verify(mockList, times(2)).add(anyString());}
}3.2验证是否发生交互
③verifyNoMoreInteractions()方法
verifyNoMoreInteractions() 方法用于验证mock对象在特定交互之后是否没有发生任何其他交互。它确保在测试中mock对象在预期的交互之后没有进行多余交互。
多余交互指的是对于被mock的对象测试代码中发生了未被预期的方法调用。这可能是因为测试代码中的某些逻辑导致了额外的方法调用。
import org.junit.Test;
import org.mockito.Mockito;public class ProcessorTest {Testpublic void processTest() {// 创建 MyService 的 mock 对象MyService myMockService Mockito.mock(MyService.class);// 创建 MyProcessor 对象并传入 mock 对象MyProcessor myProcessor new MyProcessor(myMockService);// 调用 MyProcessor 的 process() 和 process2() 方法myProcessor.process();myProcessor.process2();// 验证 mock 对象的交互Mockito.verify(myMockService).doSomething();Mockito.verify(myMockService).doSomething2();// 确保没有更多的交互发生Mockito.verifyNoMoreInteractions(myMockService);}
}④verifyZeroInteractions()方法
用于验证模拟对象上是否没有发生任何交互。它确保在测试中mock对象没有与任何其他对象进行交互。关注的是整个测试过程中是否有任何交互。
import static org.mockito.Mockito.*;// 创建mock对象
ListString mockedList mock(List.class);// 调用被测方法
mockedList.clear();// 验证是否发生了交互
verify(mockedList).clear();
verifyNoMoreInteractions(mockedList); // 确保没有其他交互第四章、Assert结果断言
4.1验证结果
①验证是否相等Equals
assertEquals(expected, actual)验证两个对象是否相等。 assertNotEquals(unexpected, actual)验证两个对象是否不相等。
示例验证 Calculator.add(3, 5) 的结果是否等于 8。如果不相等测试用例将会失败并输出指定的失败信息。
import static org.junit.jupiter.api.Assertions.assertEquals;Test
void testAddition() {int result Calculator.add(3, 5);assertEquals(8, result, The addition result should be 8);
}assertArrayEquals(expectedArray, resultArray)验证两个数组是否相等。 assertArrayEquals(expecteds, actuals, delta)验证两个浮点数数组是否相等可以指定误差范围。
示例验证 expectedArray 和 resultArray 是否相等。如果两个数组不相等测试用例将会失败并输出指定的失败信息。
import static org.junit.jupiter.api.Assertions.assertArrayEquals;Test
void testArrayEquality() {int[] expectedArray {1, 2, 3};int[] resultArray {1, 2, 3};assertArrayEquals(expectedArray, resultArray, The arrays should be equal);
}②验证结果真假
assertTrue(): 期待结果为true assertFalse(): 期待结果为false
示例验证 number 是否大于 0。如果条件不满足测试用例将会失败并输出指定的失败信息。
import static org.junit.jupiter.api.Assertions.assertTrue;Test
void testIsPositive() {int number 10;assertTrue(number 0, The number should be positive);
}③验证结果是否为null
assertNull(object)期待结果为空。 assertNotNull(object): 期待结果为非空
示例验证 obj 是否为空。如果对象不为空测试用例将会失败并输出指定的失败信息。
import static org.junit.jupiter.api.Assertions.assertNull;Test
void testObjectNull() {Object obj null;assertNull(obj, 对象应为空);
}④验证对象引用
assertSame(object1, object2)验证两个对象引用是否指向同一个对象。 assertNotSame(object1, object2)验证两个对象引用是否不指向同一个对象。
示例验证 obj1 和 obj2 是否引用同一个对象。如果两个对象引用不同的对象测试用例将会失败并输出指定的失败信息。
import static org.junit.jupiter.api.Assertions.assertSame;Test
void testObjectReference() {Object obj1 new Object();Object obj2 obj1;assertSame(obj1, obj2, 两个对象应该引用同一个对象);
}⑤验证是否满足指定条件
assertThat(actual, matcher)使用Matcher对象验证实际值是否满足指定条件。 assertThat 方法接受两个参数实际值和Matcher对象。Matcher对象定义了对实际值的特定条件例如包含特定子串、大于某个值等。通过使用Matcher对象可以实现更加灵活和具体的断言验证。 示例1
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;// 示例验证字符串是否包含指定子串
String actual Hello World;
MatcherString containsString containsString(Hello);
assertThat(actual, containsString);示例2 // 示例验证数字是否大于指定值
int actualNumber 10;
MatcherInteger greaterThan greaterThan(5);
assertThat(actualNumber, greaterThan);4.2使结果直接失败
⑥使测试用例失败fail()
直接使测试用例失败可用于标记测试用例未通过的情况。
import static org.junit.jupiter.api.Assertions.fail;Test
void testSomething() {// 执行一些测试逻辑// 如果满足特定条件则强制测试失败if (conditionIsMet) {fail(Test 测试 失败 because xxxx);}
}