5

java中有没有办法检查某个方法是否在另一个方法中被调用?我正在测试一个类和我在播放声音时遇到问题的方法,并且几乎没有办法在不更改代码的情况下获取播放的音频文件(内部类中的私有属性)。然而,该方法播放声音的方式是调用播放单个声音的方法(playSadMusic、playHappyMusic 等)。这些方法位于我必须为其创建模拟对象的接口中。我对如何进行测试有点困惑。有什么想法吗?除了检查是否调用了某个方法之外,关于我如何测试它的任何其他想法都是受欢迎的。

我正在使用 JMock 2.6.0 和 JUnit 4

音频接口

public interface StockTickerAudioInterface {

    public abstract void playHappyMusic();

    public abstract void playSadMusic();

    public abstract void playErrorMusic();
}

花药接口我必须为

public interface StockQuoteGeneratorInterface {
    public abstract StockQuoteInterface getCurrentQuote() throws Exception;

    public abstract String getSymbol();

    public abstract void setSymbol(String symbol);

    public abstract StockQuoteGeneratorInterface createNewInstance(String symbol);

}

被测试的类

public class StockQuoteAnalyzer {
    private StockTickerAudioInterface audioPlayer = null;
    private String symbol;
    private StockQuoteGeneratorInterface stockQuoteSource = null;

    private StockQuoteInterface lastQuote = null;
    private StockQuoteInterface currentQuote = null;


    public StockQuoteAnalyzer(String symbol,
        StockQuoteGeneratorInterface stockQuoteSource,
        StockTickerAudioInterface audioPlayer)
        throws InvalidStockSymbolException, NullPointerException,
        StockTickerConnectionError {
        super(); 

    // Check the validity of the symbol.
        if (StockTickerListing.getSingleton().isValidTickerSymbol(symbol) == true){
            this.symbol = symbol;
        } else {
        throw new InvalidStockSymbolException("Symbol " + symbol
                + "not found.");
        }
        if (stockQuoteSource == null) {
             throw new NullPointerException(
                "The source for stock quotes can not be null");
        }
        this.stockQuoteSource = stockQuoteSource;
        this.audioPlayer = audioPlayer;
    }
    public double getChangeSinceLast() {
        double retVal = 0.0;
        if (this.lastQuote != null) {
            double delta = this.currentQuote.getLastTrade() - this.lastQuote.getLastTrade();
            retVal = 100 * (delta / this.lastQuote.getLastTrade());
           }
           return retVal;
    }

    public double getChangeSinceYesterday() {
        double delta = (this.currentQuote.getLastTrade() - this.currentQuote
            .getClose());
        return 100 * (delta / this.currentQuote.getClose());

    }

    public void playAppropriateAudio() {
        if ((this.getChangeSinceYesterday() > 2)
            || (this.getChangeSinceLast() > 0.5)) {
            audioPlayer.playHappyMusic();
    }

        if ((this.getChangeSinceYesterday() < -2)
            || (this.getChangeSinceLast() < -0.5)) {
            audioPlayer.playSadMusic();
        }
    }

}
4

4 回答 4

9

如果您使用Mockito,您可以使用verify()来检查方法被调用的次数。像这样使用它:

verify(mockedObject, times(1)).methodToValidate();

您可以检查是否methodToValidate()使用特定字符串 ei 调用了verify(mockedObject, times(1)).methodToValidate("a specific value");或者你可以像这样使用它anyString()verify(mockedObject, times(1)).methodToValidate(anyString());.

除非使用您指定的参数调用此方法,否则测试将失败

在此处阅读有关验证的更多信息。

更新

由于您编辑的帖子表明您正在使用 jMock,因此快速谷歌搜索向我展示了使用 jMock 及其expect方法可以实现类似的行为。它的用法如下:

mockedObject.expects(once()).method("nameOfMethod").with( eq("An optional paramter") );

更详细的解释可以通过阅读 jMocks入门页面找到

于 2013-05-15T07:32:06.680 回答
2

说你有一个child()被调用的方法parent()

public void parent() {
  child();
}

child()要获取调用它的最后一个方法,您可以使用StackTraceElement

public void child() {
  StackTraceElement[] traces = Thread.currentThread().getStackTrace();
  boolean check = false;
      for(StackTraceElement element : traces) {
         if(check) {
            System.out.println("Calling method - " + element.getMethodName());
         }
         if(element.getMethodName().equals("child")) {
        check = true;
         }
      }
}
于 2013-05-15T07:26:42.930 回答
0

如果您正在使用要检查它们是否被调用的方法编写模拟对象,则可以以在调用它们时引发一些标志的方式来实现这些方法,例如

public void playHappyMusic() {
    this.wasCalled = true;
}

wasCalled作为公共(或带有吸气剂)类变量。然后你只需检查标志。

于 2013-05-15T07:30:46.420 回答
-1

如果您与调用方法在同一个线程中,您可以通过以下方式在任何给定时刻检查堆栈跟踪:

Thread.currentThread().getStackTrace()

您可以像这样查看调用了什么方法:

for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
            System.out.println(ste);
        }

例如:

public class Test {

    public static void main (String[]s){
        Test  test = new Test();
        test.makeTest();
    }

    public void makeTest(){
        for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
            System.out.println(ste);
        }
    }

结果是

java.lang.Thread.getStackTrace(Unknown Source)
Test.makeTest(Test.java:17)
Test.main(Test.java:11)
于 2013-05-15T07:29:04.810 回答