如何找出Method是否已调用给定实例。喜欢"对象obj"检查obj是否称为"等于"方法与否

时间:2015-01-06 08:33:18

标签: java object methods

我想知道是否为该实例调用某个对象的方法。

在java中可以吗?

喜欢......

class Button {
 public void focus(){}
 public void setName(){}
}

class MyTest {
public static void main(String[] args){
    Button button = new Button();
    button.focus();

    // I want to find out on button instance whether focus() or setName() is called or not.
    whetherMethodCalled(button);
    // OR
    whetherMethodCalled(button, 'focus');
    whetherMethodCalled(button, 'setName');
  }
}

编辑:忘记添加Button类是我无法修改的第三方类...另外我想在我的代码中检查方法是否已根据该方法调用了给定的对象实例我必须写一些代码。

4 个答案:

答案 0 :(得分:0)

您可以模拟按钮并在MyTest中验证必须调用该方法的次数。使用Mockito你可以模拟并存根你的methods(Stubbing void需要从when(Object)开始的不同方法,因为编译器不喜欢括号内的void方法)然后使用verify语句验证它

verify(mockButton, times(1)).focus();
verify(mockButton, times(1)).setName();

答案 1 :(得分:0)

如果在许多地方需要并涉及复杂的事情,我建议使用Mockito来测试您的代码。使用它可以验证是否调用了方法(也调用了多少次)

答案 2 :(得分:0)

您可以在第三方Button类上编写一个包装类,通过该类可以对Button类进行所有调用。 这个包装类可以跟踪是否已经调用了每个方法

class ButtonCaller {

    private Button button = null;
    private boolean focusCalled;
    private boolean setNameCalled;

    public ButtonCaller() {
        button = new Button();
        focusCalled = false;
        setNameCalled = false;
    }

    public void focus() {
        button.focus();
        focusCalled = true;
    }

    public void setName() {
        button.setName();
        setNameCalled = true;
    }

    public void whetherMethodCalled(ButtonMethod method) {
        switch (method) {
        case FOCUS:
            return focusCalled;
        case SET_NAME:
            return setNameCalled;
        }
        throw new RuntimeException("Unknown ButtonMethod !!!");
    }

    public static Enum ButtonMethod {
        FOCUS,
        SET_NAME;
    }
}

答案 3 :(得分:0)

为了减少额外的工作,可能使用JConsole或其他工具分析您的应用程序足以显示某些方法是否已运行。另一种选择是使用像EMMA这样的代码覆盖工具来检测死代码。在http://java-source.net/open-source/profilers有一个Java的开源分析器列表,EMMA在http://emma.sourceforge.net/

通过一些额外的工作,AspectJ可用于在不改变现有代码的情况下拦截方法调用。例如,以下内容将拦截对Button.focus()

的调用
@Aspect
public class InterceptButtonMethods {
  @Before("execution(* Button.focus())")
  public void beforeInvoke() {
    System.out.println("Button.focus invoked");
    incrementFocusCount();
  }
}

如果有更多的额外工作可以,有一种方法可以将所有调用包装到Button的focus()和setName()方法中,这样除了正常的函数外,它们还会更新单独的计数器。这可以通过在YourButton类中扩展Button来完成,除了一些带有getter,setter和increment方法的int计数器之外,它与Button相同。和countingFocus()和countingSetName()方法分别更新它们的计数器并调用focus()和setName(),例如在大纲中:

Class YourButton extends Button { 
  int focusCount; 
  int setNameCount
  int getFocusCount() {return this.focusCount;}
  void setFocusCount(int counter) {this.focusCount = counter} // optional to reset counter
  void incrementFocusCount() {this.focusCount = getFocusCount() + 1;)
  ...
  void countingFocus() {
    incrementFocusCount();
    focus()
  }
  ...
}