簡體   English   中英

帶輸入的方法上的Java單元測試

[英]Java Unit Test on method with input

當我使用方法“ execute(p)”時,必須選擇一個項目時會有一個列表:

@Override
public void execute(Player p) {
    // listchoser with items available
    ListChoser lc = new ListChoser();
    Object itemChosen;
    itemChosen = lc.chose("Which item?", p.getCurrentRoom().getItems());
    System.out.println("You chose " + itemChosen.toString());
    // put item effect on player
    ((Item) itemChosen).effect(p);
    // remove item from current room
    p.getCurrentRoom().removeItem(itemChosen);
}

我必須對其進行一些單元測試,以便在這里進行操作:

Player c;
Action useAction;

@Before
public void initiliaze() {
    c = new Player("Test", 100, 100,100);
    c.setCurrentRoom(new Room("Debug Room", false));
    useAction = new UseAction();
}

@Test
public void testUseAction(){
    List<? super Item> l = c.getCurrentRoom().getItems();
    int nbItems = l.size();
    useAction.execute(c);
    assertEquals(nbItems-1, c.getCurrentRoom().getItems().size());
}

啟動此類測試時,我遇到了一些麻煩:當我僅應使用默認值(例如0)時,要求輸入

我建議將execute()方法拆分為2個單獨的方法,因此它們中的第一個僅接受輸入,對其進行處理並將操作結果傳遞給包含所有其他邏輯的第二個方法。

這使您的代碼符合SOLID的 “單一職責”原則,並且還可以測試負責邏輯的那部分代碼,而無需用戶提供任何輸入(您可以傳遞一些准備好的對象)

交互式代碼和單元測試不匹配。 這就是為什么“測試優先”方法有助於編寫干凈且可測試的代碼的原因。 如果事后編寫測試代碼,則出於可測試性,您不得不花時間重寫程序代碼。

一種快速而骯臟的解決方案是添加另一個方法,並從現有方法中調用它,如下所示:

@Override
public void execute(Player p) {
    execute(Player p, new ListChoser());
}

public void execute(Player p, ListChoser lc) {
    Object itemChosen;
    if (lc != null) {
        itemChosen = lc.chose("Which item?", p.getCurrentRoom().getItems());
        System.out.println("You chose " + itemChosen.toString());
    }
    else { //add exception handling if list is empty
        itemChosen = p.getCurrentRoom().getItems()[0];
    }
    // put item effect on player
    ((Item) itemChosen).effect(p);
    // remove item from current room
    p.getCurrentRoom().removeItem(itemChosen);
}

並使用這種新方法進行測試,例如:

@Test
public void testUseAction(){
    List<? super Item> l = c.getCurrentRoom().getItems();
    int nbItems = l.size();
    useAction.execute(c, null); //use null for default behaviour
    assertEquals(nbItems-1, c.getCurrentRoom().getItems().size());
} 

這樣,您至少可以測試代碼的非交互部分。

更好的解決方案是將ListChoser完全重新設計為接口,並實現InteractiveListChoserTestListChoser 將類型(=接口)與實現(= class)分開是一種設計原理,非常適合單元測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM