簡體   English   中英

如何測試類方法是否正在從類的私有對象之一調用另一個方法

[英]How can I test if a class method is calling another method from one of the classes's private objects

我正在嘗試為一個項目創建單元測試。 在我的項目中,我有一個菜單類和一個VerticalOptions類。

我的菜單類有一個私有的VerticalOptions對象和一個公共的handleInput方法。 當我調用菜單的handleInput(key)方法時,根據我提供的鍵,它會執行不同的操作,即調用VerticalOptions對象的不同方法。

我想做一個unitTest來查看被調用的方法是否正確,我該怎么做?

我嘗試將Mockito間諜添加到菜單中,但是由於我想測試被調用的方法是否是私有VerticalOptions對象中的方法,因此它實際上不起作用。

在使用getVerticalOptions方法獲取間諜程序之后,我還嘗試了將間諜放在VerticalOptions對象上,但是它也不起作用。

public void handleInput(InputKey key)
{
    switch (key) {
        case S:
        case DOWN:
            optionsInterface.cycleDown();
            break;
        case W:
        case UP:
            optionsInterface.cycleUp();
            break;
        case SPACE:
        case ENTER:
            optionsInterface.select();
            break;
        default:
            break;
    }
}


@Test
public void testInput() {
    MainMenu menu = new MainMenu(game);
    VerticalButtonInterface buttonInterface = menu.getOptionsInterface();
    VerticalButtonInterface spy = spy(buttonInterface);

    menu.handleInput(InputKey.DOWN);
    verify(spy, times(1)).cycleDown();
}

這是我的測試失敗:

想要但不被調用:verticalButtonInterface.cycleDown(); ->在MenuTest.testInput(MenuTest.java:60)上,實際上與該模擬的交互為零。

我將為您提供另一種觀點。 我已經看到很多人走錯了道路,當您這樣做時,其他所有事情都會變得難以執行/測試,這正是您現在正在做的事情。

從這里開始,您要達到什么目標?

我想測試並確保某種方法被稱為...

這是一件好事嗎? 什么不是單元測試? 那就是對代碼的深入了解。

為什么? 因為每次您對代碼進行微小的更改時,由於這些深厚的知識,您都必須更改測試。 如果您有1000項測試,那您將步履艱難。

好的,現在我們知道了問題所在,那么如何解決呢? 好吧,首先讓我們確保無需進行深入的代碼測試就可以進行測試。

我們該怎么做? 好吧,假設您的代碼添加了一個額外的步驟,即設置狀態的標志。 您可能有一個存儲結果狀態的標志...

您有3個要調用的方法,所以您將需要3個不同的狀態,因此請創建一個反映該變量的變量,它可以是字符串,枚舉或其他使您滿意的變量。

例如,假設我們創建一個具有3個可能值的字符串:cycleDown,cycleUp和select。

您的代碼開始看起來像:

public string handleInput(InputKey key)
{
      String state = determineState(key);
      SomeType someResult = executeActionForState(state);
}

public String determineState(string key)
{

    String state = "";
     switch (key) {
    case S:
    case DOWN:
        state = "cycleDown";
        break;
    case W:
    case UP:
        state = "cycleUp";
        break;
    case SPACE:
    case ENTER:
        state = "select";
        break;
    default:
        break;
}

return state;
}

public void executeActionForState(string state)
{
     if ( state == "cycleup" ) {
     }

     etc etc
}

現在,我不一定要像這樣編寫您的示例,這有點強迫,它取決於您對代碼執行的其他操作,但這只是為了說明如何將功能與UI方面分開。

我可以輕松地測試狀態方法,可以更改其代碼,而不必更改測試,因為該測試將查看輸入和輸出,而不是如何實現。

單元測試是關於功能的,它涉及的是簡單的測試,一旦創建就不需要進行更改。 驗證方法已被調用不會給您帶來任何價值,因為您不知道該方法以后會做什么。

您可以通過其他方式測試UI內容,而單元測試僅與正確的功能有關。 如果您沒有明確區分,那么您將很難維護測試,在您放棄之前,它將越來越難。

您將測試您是否獲得了正確的狀態,然后測試了cycleUp方法根據您的要求執行了正確的操作,這就是您知道每個部分獨立工作的方式。 稍后,您開始研究集成測試,自動UI測試,但這是不同的。 保持單元測試的目的,保持簡單,使其不與其他代碼綁定,然后一切都變得簡單。 您無需進行太多模擬,也不必為復雜的設置擔心太多,也不必每次代碼更改時都更改測試。

現在,要解決問題的最后一部分,私有方法,您可以通過觀察它們的輸出來對其進行測試。 您必須在類中擁有一些公共的東西,這些東西在調用私有方法時會發生變化。 所以測試一下。

暫無
暫無

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

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