Mock方法時(shí)的參數(shù)匹配

??在mock方法時(shí),對(duì)于方法的參數(shù)匹配是有要求的,只有要執(zhí)行的方法的參數(shù)匹配mock方法里面的參數(shù)時(shí),該mock方法才會(huì)起作用。Powermock提供了很多種參數(shù)匹配的方式,比如,如果需要精確地匹配參數(shù),可以使用equal方式;如果需要靈活地匹配參數(shù),可以使用any方式。下面,我們就來簡單地介紹下mock方法時(shí)的參數(shù)匹配。

一、精確匹配

??還是先來看下被測試代碼:

public class EmployeeService {
    public Employee findEmployeeByEmail(String email) {
        throw new UnsupportedOperationException();
    }

    public boolean employeeExists(Employee employee) {
        throw new UnsupportedOperationException();
    }
}
public class EmployeeController {
    private EmployeeService employeeService;

    public EmployeeController(EmployeeService employeeService) {
        this.employeeService = employeeService;
    }

    public Employee findEmployeeByEmail(String email) {
        return employeeService.findEmployeeByEmail(email);
    }

    public boolean isEmployeeEmailAlreadyTaken(String email) {
        return employeeService.employeeExists(new Employee(email));
    }
}

??代碼很直觀,EmployeeController類中定義了兩個(gè)方法,一個(gè)是findEmployeeByEmail,根據(jù)email查詢員工,調(diào)用employeeService.findEmployeeByEmail方法;另一個(gè)方法是isEmployeeEmailAlreadyTaken方法,判斷某個(gè)員工是否存在,調(diào)用employeeService.employeeExists方法。
??
??現(xiàn)在看下測試代碼:

public class EmployeeControllerTest {
    @Test
    public void testFindEmployeeByEmail() {
        EmployeeService employeeService = PowerMockito.mock(EmployeeService.class);
        Employee employee = new Employee();
        PowerMockito.when(employeeService.findEmployeeByEmail(Mockito.eq("123@abc.com"))).thenReturn(employee);

        EmployeeController employeeController = new EmployeeController(employeeService);

        Assert.assertSame(employee, employeeController.findEmployeeByEmail("123@abc.com"));
        Assert.assertNull(employeeController.findEmployeeByEmail("123@dce.com"));
    }
}

??從上述測試方法可以看到,在模擬employeeService.findEmployeeByEmail方法時(shí)使用了eq方法,這個(gè)就是精確匹配模式,執(zhí)行參數(shù)完全匹配該參數(shù)時(shí),才會(huì)返回employee。

二、模糊匹配

??有時(shí)候,我們想要在匹配參數(shù)時(shí)更靈活些,可以使用模糊匹配??聪孪旅娴臏y試方法:

public class EmployeeControllerTest {
    @Test
    public void testFindEmployeeByEmail() {
        EmployeeService employeeService = PowerMockito.mock(EmployeeService.class);
        Employee employee = new Employee();
        PowerMockito.when(employeeService.findEmployeeByEmail(Mockito.startsWith("123"))).thenReturn(employee);

        EmployeeController employeeController = new EmployeeController(employeeService);

        Assert.assertSame(employee, employeeController.findEmployeeByEmail("123@abc.com"));
        Assert.assertSame(employee, employeeController.findEmployeeByEmail("123@dce.com"));
        Assert.assertNull(employeeService.findEmployeeByEmail("456@abc.com"));
    }
}

??該例中,使用startWith替換了eq,可以看到當(dāng)參數(shù)為"123@abc.com"和"123@456.com"時(shí),都返回了employee,而"456@abc.com"則返回了Null??梢姶藭r(shí)參數(shù)是匹配任何以"123"開頭的字符串,這種用法能夠使得參數(shù)的匹配相對(duì)于eq方式更靈活些。

三、任意匹配

??另外一種參數(shù)匹配,即無論入?yún)⑹鞘裁粗担颊J(rèn)為是匹配的。

public class EmployeeControllerTest {
    @Test
    public void testFindEmployeeByEmail() {
        EmployeeService employeeService = PowerMockito.mock(EmployeeService.class);
        Employee employee = new Employee();
        PowerMockito.when(employeeService.findEmployeeByEmail(Mockito.anyString())).thenReturn(employee);

        EmployeeController employeeController = new EmployeeController(employeeService);

        Assert.assertSame(employee, employeeController.findEmployeeByEmail("123@abc.com"));
        Assert.assertSame(employee, employeeController.findEmployeeByEmail("123@dce.com"));
        Assert.assertSame(employee, employeeService.findEmployeeByEmail("456@abc.com"));
    }
}

??此例中,使用了anyString方式,即無論入?yún)⑹鞘裁醋址挤祷豦mployee。此時(shí)可以看出給定的三個(gè)字符串,都返回了employee。

四、自定義匹配

??除了使用自帶的匹配方式之外,還可以自己定義相應(yīng)的參數(shù)匹配方式。

public class EmployeeControllerTest {
    @Test
    public void testIsEmployeeEmailAlreadyTaken() {
        EmployeeService employeeService = PowerMockito.mock(EmployeeService.class);
        final String email = "123@abc.com";
        PowerMockito.when(employeeService.employeeExists(Mockito.argThat(new ArgumentMatcher<Employee>() {
            @Override
            public boolean matches(Object employee) {
                return ((Employee) employee).getEmail().equals(email);
            }
        }))).thenReturn(true);

        EmployeeController employeeController = new EmployeeController(employeeService);

        Assert.assertTrue(employeeController.isEmployeeEmailAlreadyTaken(email));
    }
}

??這個(gè)例子看上去稍微有點(diǎn)復(fù)雜。從業(yè)務(wù)代碼可以看出,EmployeeController類的方法isEmployeeEmailAlreadyTaken和EmployeeService類的方法參數(shù)并不一樣,但是又有所關(guān)聯(lián),是使用isEmployeeEmailAlreadyTaken的入?yún)?gòu)造了一個(gè)新的入?yún)ⅰ,F(xiàn)在,我們要想精確匹配入?yún)?,就需要自己?shí)現(xiàn)matcher方法。

??除了上述的一些例子外,Mockito還提供了許多別的參數(shù)匹配的方法,比如any、matches、isNull等等。如何使用這些匹配方式,需要根據(jù)自己的需求來選擇相應(yīng)的模式實(shí)現(xiàn)。另外,上面介紹的參數(shù)匹配同樣適用于Mockito.verify。

??最后,強(qiáng)調(diào)一點(diǎn),對(duì)于多個(gè)參數(shù)的方法,如果我們其中一個(gè)參數(shù)使用了參數(shù)匹配模式,那么所有的參數(shù)都必須使用參數(shù)匹配模式,下面的例子中的使用方式就是錯(cuò)誤的:

PowerMockito.when(mock.findEmployeeByFirstNameAndLastName("Deep", Mockito.anyString())).thenReturn(null);

??正確的方式為:

PowerMockito.when(mock.findEmployeeByFirstNameAndLastName(Mockito.eq("Deep"), Mockito.anyString())).thenReturn(null);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 概要 64學(xué)時(shí) 3.5學(xué)分 章節(jié)安排 電子商務(wù)網(wǎng)站概況 HTML5+CSS3 JavaScript Node 電子...
    阿啊阿吖丁閱讀 9,828評(píng)論 0 3
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,545評(píng)論 19 139
  • 一、Java 簡介 Java是由Sun Microsystems公司于1995年5月推出的Java面向?qū)ο蟪绦蛟O(shè)計(jì)...
    子非魚_t_閱讀 4,551評(píng)論 1 44
  • 閱讀藝術(shù)的精髓在于不斷提出問題并嘗試精確正確地回答問題。我們可以以筆記的形式來對(duì)待這些問題,你需要把答案寫出來,因...
    大漢養(yǎng)生閱讀 553評(píng)論 0 0
  • 爸爸在那里種過菜,種過糧,也種過各種水果,但是他種出來的桃子是最好吃的。早桃面而甜,不亂核兒皮子也能輕松剝落,來買...
    阿爾他霞閱讀 1,921評(píng)論 18 29

友情鏈接更多精彩內(nèi)容