日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Mockito

發(fā)布時(shí)間:2023/12/9 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Mockito 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Mockito

本文整理自 B站 UP主 心藍(lán)說Java 汪文君Mockito實(shí)戰(zhàn)視頻筆記

introduction

Mockito is a mocking framework that tastes really good. It lets you write beautiful tests with a clean & simple API. Mockito doesn’t give you hangover because the tests are very readable and they produce clean verification errors. Read more about features & motivations.

significance of mockito

Automated tests are a safety net. They run and notify if the system is broken so that the offending code can be fixed very quickly. If a test suite runs for an hour, the purpose of quick feedback is compromised.

The following are example s of testing-unfriendly behaviors:

  • Accquiring a database connection and fetching/updating data
  • Connecting to the Internet and downloading files
  • Interacting with an SMTP server to send an e-mail
  • Looking up JNDI (Java Naming and Directory Interface])
  • Invoking a web service
  • Performing I/O operations, such as printing a report

Mockito plays a key role in mocking external dependencies.

1.**how to mock **

  • @RunWith(MockitoJUnitRunner.class)
@RunWith(MockitoJUnitRunner.class) public class AccountLoginControllerTest {private AccountDao accountDao;private HttpServletRequest request;private AccountLoginController controller;@Beforepublic void setUp() {this.accountDao = Mockito.mock(AccountDao.class);this.request = Mockito.mock(HttpServletRequest.class);this.controller = new AccountLoginController(accountDao);}@Testpublic void testLoginSuccess() {Account account = new Account();Mockito.when(request.getParameter("username")).thenReturn("alex");Mockito.when(request.getParameter("password")).thenReturn("123456");Mockito.when(accountDao.findAccount(anyString(), anyString())).thenReturn(account);assertThat(controller.login(request), equalTo("index.jsp"));}@Testpublic void testLoginFailure() {Mockito.when(accountDao.findAccount(anyString(), anyString())).thenReturn(null);assertThat(controller.login(request), equalTo("/login"));}@Testpublic void testLogin505() {Mockito.when(accountDao.findAccount(anyString(), anyString())).thenThrow(UnsupportedOperationException.class);assertThat(controller.login(request), equalTo("505"));} }
  • MockitoAnnotations.initMocks(this) and @Mock

    public class AccountControllerTest {private AccountLoginController controller;private AccountDao accountDao;@Mockprivate HttpServletRequest request;@Beforepublic void setUp(){MockitoAnnotations.initMocks(this);accountDao = Mockito.mock(AccountDao.class);controller = new AccountLoginController(accountDao);}@Testpublic void testLoginSuccess(){Mockito.when(accountDao.findAccount(anyString(), anyString())).thenReturn(new Account());assertThat(controller.login(request), equalTo("index.jsp"));} }
  • MockitoRule mockRule = MockitoJUnit.rule()

    public class AccountControllerMockByRuleTest {@Rulepublic MockitoRule mockitoRule = MockitoJUnit.rule();@Mock(answer = Answers.RETURNS_SMART_NULLS)private AccountDao accountDao;@Testpublic void testLogin(){Account account = accountDao.findAccount(anyString(), anyString());assertNotNull(account);} }
  • mock 方法內(nèi)部類

    public class DeepMockOrderServiceTest {@Mockprivate Order order;@Mock(answer = Answers.RETURNS_DEEP_STUBS)private OrderService service;@Beforepublic void setUp() {MockitoAnnotations.initMocks(this);}@Testpublic void testOrderService(){ // Mockito.when(service.getOrder()).thenReturn(order); // order.foo();service.getOrder().foo();} }

2.how to stubbing

  • stubbing void method
  • stubbing method with exception
  • stubbing consecutive calls(iterator-style-stubbing)
  • stubbing with callbacks
  • stubbing with real call
import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.runners.MockitoJUnitRunner;import java.util.ArrayList; import java.util.List;import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.instanceOf; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; import static org.mockito.Mockito.*;@RunWith(MockitoJUnitRunner.class) public class StubbingTest {private List<String> list;@Beforepublic void init(){this.list = mock(ArrayList.class);}/*** when ... Then ...*/@Testpublic void howToUseStubbing(){when(list.get(0)).thenReturn("first");assertThat(list.get(0), equalTo("first"));when(list.get(anyInt())).thenThrow(new RuntimeException());try {list.get(0);fail();}catch (Exception e){assertThat(e, instanceOf(RuntimeException.class));}}/*** 測試無返回值的方法*/@Testpublic void howToStubbingVoidMethod(){doNothing().when(list).clear();list.clear();// 驗(yàn)證執(zhí)行次數(shù)verify(list, times(1)).clear();// 拋出異常doThrow(RuntimeException.class).when(list).clear();try {list.clear();fail();}catch (Exception e){assertThat(e, instanceOf(RuntimeException.class));}}/*** 測試有返回值的方法*/@Testpublic void stubbingDoReturn(){when(list.get(0)).thenReturn("first");doReturn("second").when(list).get(1);assertThat(list.get(0), equalTo("first"));assertThat(list.get(1), equalTo("second"));}/*** 每次執(zhí)行方法返回不同值*/@Testpublic void iterateStubbing(){when(list.size()).thenReturn(1, 2, 3, 4); // when(list.size()).thenReturn(1).thenReturn(2).thenReturn(3).thenReturn(4);assertThat(list.size(), equalTo(1));assertThat(list.size(), equalTo(2));assertThat(list.size(), equalTo(3));assertThat(list.size(), equalTo(4));assertThat(list.size(), equalTo(4));}/*** 返回自定義值*/@Testpublic void stubbingAnswer(){when(list.get(anyInt())).thenAnswer(invocationOnMock -> {Integer index = invocationOnMock.getArgumentAt(0, Integer.class);return String.valueOf(index * 10);});assertThat(list.get(0), equalTo("0"));assertThat(list.get(777), equalTo("7770"));}/*** mock對象真實(shí)調(diào)用方法*/@Testpublic void stubbingWithRealMethod(){StubbingService service = mock(StubbingService.class);when(service.getStr()).thenReturn("alex");assertThat(service.getStr(), equalTo("alex"));when(service.getInt()).thenCallRealMethod();assertThat(service.getInt(), equalTo(10));}@Afterpublic void destroy(){reset(this.list);} }public class StubbingService {public int getInt(){return 10;}public String getStr(){throw new RuntimeException();} }

3.mockito spying

Spying on real objects can be associated with “partial mocking” concept. Before the release 1.8, Mockito spies were not real partial mocks. The reason was we thought partial mock is a code smell. At some point we found legitimate use cases for partial mocks(3rd party interfaces, interim refactoring of legacy code).

import java.util.ArrayList;import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertThat; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when;@RunWith(MockitoJUnitRunner.class) public class SpyingTest {@Testpublic void testSpy(){ArrayList<String> realList = new ArrayList<>();ArrayList<String> spyList = spy(realList);spyList.add("Mockito");spyList.add("PowerMock");assertThat(spyList.get(0), equalTo("Mockito"));assertThat(spyList.get(1), equalTo("PowerMock"));assertThat(spyList.isEmpty(), equalTo(false));when(spyList.isEmpty()).thenReturn(true);when(spyList.size()).thenReturn(0);assertThat(spyList.get(0), equalTo("Mockito"));assertThat(spyList.get(1), equalTo("PowerMock"));assertThat(spyList.isEmpty(), equalTo(true));assertThat(spyList.size(), equalTo(0));} } import org.junit.Before; import org.junit.Test; import org.mockito.MockitoAnnotations; import org.mockito.Spy;import java.util.ArrayList; import java.util.List;import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertThat; import static org.mockito.Mockito.when;public class SpytingAnnotationTest {@Spyprivate List<String> list = new ArrayList<>();@Beforepublic void init(){MockitoAnnotations.initMocks(this);}@Testpublic void testSpying(){list.add("Mockito");list.add("PowerMock");assertThat(list.get(0), equalTo("Mockito"));assertThat(list.get(1), equalTo("PowerMock"));assertThat(list.isEmpty(), equalTo(false));when(list.isEmpty()).thenReturn(true);when(list.size()).thenReturn(0);assertThat(list.get(0), equalTo("Mockito"));assertThat(list.get(1), equalTo("PowerMock"));assertThat(list.isEmpty(), equalTo(true));assertThat(list.size(), equalTo(0));} }

4.Mockito Argument Matchers

  • The argument matcher plays a key role in mocking. Mock objects return expected values, but when need to return different values for different arguemnts, the argument matcher comes into play.

  • Mockito returns expected values when a method is stubbed. If the method takes arguments, the argument must match during the execution.

  • Mockito verifies argument values in natural Java style by using an objects’s equals() method.

  • Sometimes, we use argument matchers when extra flexibility is required. Mockito provides built-in matchers, such as anything(), anyDouble(), anyString(), anyList(), and anyCollection().參考鏈接

  • isA(Class clazz), any(Class clazz), eq(primitive value)

    import org.junit.Test; import org.mockito.Mockito;import java.util.ArrayList; import java.util.List;import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.nullValue; import static org.junit.Assert.assertThat; import static org.mockito.Mockito.*;public class ArgumentsMatcher {@Testpublic void basicTest(){List<Integer> list = mock(ArrayList.class);when(list.get(0)).thenReturn(100);assertThat(list.get(0), equalTo(100));assertThat(list.get(1), nullValue());}/*** diff isA(), any()*/@Testpublic void testComplex(){Foo foo = mock(Foo.class);when(foo.function(Mockito.isA(Child1.class))).thenReturn(100);int result = foo.function(new Child1());assertThat(result, equalTo(100));result = foo.function(new Child2());assertThat(result, equalTo(0));reset(foo);when(foo.function(Mockito.any(Child1.class))).thenReturn(200);result = foo.function(new Child2());assertThat(result, equalTo(200));}static class Foo{int function(Parent parent){return parent.work();}}interface Parent{int work();}class Child1 implements Parent{@Overridepublic int work() {throw new RuntimeException();}}class Child2 implements Parent {@Overridepublic int work() {throw new RuntimeException();}} }

5.Working With WildCard Matchers

  • A test invokes a method on a code under test. When the invoke method creates a new object and passess that to a mock object, the test method doesn’t have the reference of that new object. So that test cannot stub the mock method with a specific value, as the value is not available to the test mehod. In this context, we use the wildcard matchers.

  • anyXXX()

  • any()

  • isA()

  • eq()

  • etc.

    import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner;import java.io.Serializable; import java.util.Collections;import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertThat; import static org.mockito.Matchers.*; import static org.mockito.Mockito.*;@RunWith(MockitoJUnitRunner.class) public class WildCardArgumentsMatcherTest {@Mockprivate SimpleService simpleService;@Testpublic void testWildcardMethod1(){Mockito.when(simpleService.method1(anyInt(), anyString(), anyCollection(), isA(Serializable.class))).thenReturn(100);int result = simpleService.method1(1, "he", Collections.emptySet(), "Mockito");assertThat(result, equalTo(100));result = simpleService.method1(1, "he", Collections.emptyList(), "MockitoForJava");assertThat(result, equalTo(100));}@Testpublic void wildcardMethodWithSpec(){// 大范圍的在最前面stubwhen(simpleService.method1(anyInt(), anyString(), anyCollection(), isA(Serializable.class))).thenReturn(-1);// 所有參數(shù)全為wildcard,不能部分參數(shù)為wildcard// 特定值用eq(), 否則報(bào)錯(cuò)when(simpleService.method1(anyInt(), eq("alex"), anyCollection(), isA(Serializable.class))).thenReturn(100);when(simpleService.method1(anyInt(), eq("he"), anyCollection(), isA(Serializable.class))).thenReturn(200);// specific valueint result = simpleService.method1(1, "alex", Collections.emptyList(), "Mockito");assertThat(result, equalTo(100));result = simpleService.method1(1, "he", Collections.emptyList(), "Mockito");assertThat(result, equalTo(200));/* // 沒匹配上,返回類型默認(rèn)值result = simpleService.method1(1, "sdfgbgfd", Collections.emptyList(), "Mockito");assertThat(result, equalTo(0));*/// 返回wildcard值result = simpleService.method1(1, "sdfgbgfd", Collections.emptyList(), "Mockito");assertThat(result, equalTo(-1));}@Testpublic void wildcardMethod2(){doNothing().when(simpleService).method2(anyInt(), anyString(), anyCollection(), isA(Serializable.class));simpleService.method2(1, "alex", Collections.emptyList(), "Mockito");verify(simpleService, times(1)).method2(1, "alex", Collections.emptyList(), "Mockito");}@Afterpublic void destroy(){// 還原stubreset(simpleService);} }

6.Hamcrest matcher

Hamcrest provides a utility matcher class, org.hamcrest.CoreMatchers. A few methods for CoreMatchers include allOf, anyOf, both, either, descibedAs, everyItem, is, isA, anything, hasItem, hasItems, equalTo, any, instanceOf, not, nullValue, notNullValue, sameInstance, end the Instance. It also includes a few string methods such as startsWith, endWith, and containsString. All these methods return a matcher.

import org.junit.Test;import java.util.stream.Stream;import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.assertThat;public class AssertMatcherTest {@Testpublic void matcher01(){int i = 10;assertThat(i, equalTo(10));assertThat(i, not(equalTo(20)));assertThat(i, is(10));assertThat(i, not(is(20)));}@Testpublic void matcher02(){double price = 23.45;assertThat(price, either(equalTo(23.45)).or(equalTo(23.54)));assertThat(price, both(equalTo(23.45)).and(not(equalTo(23.53))));assertThat(price, anyOf(is(23.45), is(33.44), is(333.666), not(55.66)));assertThat(price, allOf(is(23.45), not(is(34.77)), not(88.78)));assertThat(Stream.of(1, 2, 3).anyMatch(i -> i > 2), equalTo(true));assertThat(Stream.of(1, 2, 3).allMatch(i -> i > 0), equalTo(true));}@Testpublic void matcher03(){double price = 23.45;assertThat("the double value assertion failed", price, either(equalTo(23.54)).or(equalTo(24.35)));} }

7.Extend Matcher

import org.hamcrest.BaseMatcher; import org.hamcrest.Description; import org.hamcrest.Factory;public class CompareThan<T extends Number> extends BaseMatcher<T> {private final T value;private final boolean greater;public CompareThan(T value, boolean greater) {this.value = value;this.greater = greater;}@Overridepublic boolean matches(Object actual) {Class<?> clazz = actual.getClass();if (clazz == Integer.class) {return greater ? (Integer) actual > (Integer) value : (Integer) actual < (Integer) value;}else if (clazz == Long.class){return greater ? (Long) actual > (Long) value : (Long) actual < (Long) value;}else if (clazz == Short.class){return greater ? (Short) actual > (Short) value : (Short) actual < (Short) value;}else if (clazz == Byte.class){return greater ? (Byte) actual > (Byte) value : (Byte) actual < (Byte) value;}else if (clazz == Float.class){return greater ? (Float) actual > (Float) value : (Float) actual < (Float) value;}else if (clazz == Double.class){return greater ? (Double) actual > (Double) value : (Double) actual < (Double) value;}else{throw new AssertionError("unsupported number type");}}@Factorypublic static <T extends Number> CompareThan<T> gt(T value){return new CompareThan<>(value, true);}@Factorypublic static <T extends Number> CompareThan<T> lt(T value){return new CompareThan<>(value, false);}@Overridepublic void describeTo(Description description) {description.appendText("compare two numbers failed");} } import org.junit.Test;import static com.heju.mockito.CompareThan.gt; import static com.heju.mockito.CompareThan.lt; import static org.hamcrest.CoreMatchers.both; import static org.junit.Assert.assertThat;public class MyAssertThatTest {@Testpublic void ltAndGt(){assertThat(12, gt(10));assertThat(12, both(gt(10)).and(lt(13)));} }

refactor code

public interface CompareNumber<T extends Number> {boolean compare(T expected, T actual); }public class CompareNumberImpl<T extends Number> implements CompareNumber<T>{private final boolean greater;public CompareNumberImpl(boolean greater) {this.greater = greater;}@Overridepublic boolean compare(T actual, T expected) {Class<?> clazz = expected.getClass();if (clazz == Integer.class) {return greater ? (Integer) expected > (Integer) actual : (Integer) expected < (Integer) actual;}else if (clazz == Long.class){return greater ? (Long) expected > (Long) actual : (Long) expected < (Long) actual;}else if (clazz == Short.class){return greater ? (Short) expected > (Short) actual : (Short) expected < (Short) actual;}else if (clazz == Byte.class){return greater ? (Byte) expected > (Byte) actual : (Byte) expected < (Byte) actual;}else if (clazz == Float.class){return greater ? (Float) expected > (Float) actual : (Float) expected < (Float) actual;}else if (clazz == Double.class){return greater ? (Double) expected > (Double) actual : (Double) expected < (Double) actual;}else{throw new AssertionError("unsupported number type");}} } import org.hamcrest.BaseMatcher; import org.hamcrest.Description; import org.hamcrest.Factory;public class CompareNumberMatcher<T extends Number> extends BaseMatcher<T> {private final T value;private final CompareNumber<T> COMPARE;public CompareNumberMatcher(T value, boolean greater) {this.value = value;this.COMPARE = new CompareNumberImpl<>(greater);}@Overridepublic boolean matches(Object actual) {return this.COMPARE.compare(value, (T) actual);}@Factorypublic static <T extends Number> CompareNumberMatcher<T> gt(T value){return new CompareNumberMatcher<T>(value, true);}@Factorypublic static <T extends Number> CompareNumberMatcher<T> lt(T value){return new CompareNumberMatcher<>(value, false);}@Overridepublic void describeTo(Description description) {description.appendText("compare two numbers failed");} } import org.junit.Test;import static org.hamcrest.CoreMatchers.both; import static org.junit.Assert.assertThat;public class MyAssertThatTest {@Testpublic void compareThan(){assertThat(12, CompareNumberMatcher.gt(10));assertThat(12, both(CompareNumberMatcher.gt(10)).and(CompareNumberMatcher.lt(13)));} }

總結(jié)

以上是生活随笔為你收集整理的Mockito的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。