java 检查一个方法是否在另一个方法中被调用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16558995/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Check if a method was called inside another method
提问by user2337029
Is there any way in java to check if a certain method was called inside another method? I am testing a class and the method I am having trouble with plays sound and there is virtually no way of getting the audio file that is played(private attribute inside an inner class) without changing the code. However the way the method plays sounds is it calls a method that plays a single sound (playSadMusic, playHappyMusic, etc). Those methods are in an interface that I have to create a mock object for. I'm a little stuck on how I would exactly go about testing this. Any thoughts? Any other ideas on how I could possibly test this other than check if a certain method was call are welcome.
java中有什么方法可以检查某个方法是否在另一个方法中被调用?我正在测试一个类,我在播放声音时遇到问题的方法几乎没有办法在不更改代码的情况下获取播放的音频文件(内部类中的私有属性)。然而,该方法播放声音的方式是调用一个播放单个声音的方法(playSadMusic、playHappyMusic 等)。这些方法位于我必须为其创建模拟对象的接口中。我有点不知道我将如何进行测试。有什么想法吗?除了检查某个方法是否被调用之外,关于我如何可能测试这个的任何其他想法都是受欢迎的。
I am using JMock 2.6.0 and JUnit 4
我正在使用 JMock 2.6.0 和 JUnit 4
the audio inteface
音频接口
public interface StockTickerAudioInterface {
public abstract void playHappyMusic();
public abstract void playSadMusic();
public abstract void playErrorMusic();
}
anther interface I have to create a mock for
我必须为另一个界面创建一个模拟
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);
}
the class being tested
被测试的班级
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();
}
}
}
回答by John Snow
If you use Mockito
you can use verify()
to check the number of times a method was called. Use it like this:
如果你使用Mockito
你可以verify()
用来检查一个方法被调用的次数。像这样使用它:
verify(mockedObject, times(1)).methodToValidate();
You can check if methodToValidate()
was called with a specific string, e.i verify(mockedObject, times(1)).methodToValidate("a specific value")
; or you can use it with anyString()
like this: verify(mockedObject, times(1)).methodToValidate(anyString());
.
您可以检查是否methodToValidate()
使用特定字符串 ei 调用verify(mockedObject, times(1)).methodToValidate("a specific value")
;或者你可以使用它anyString()
是这样的:verify(mockedObject, times(1)).methodToValidate(anyString());
。
Unless this method is called with your specified paramterer, the test will fail
除非使用您指定的参数调用此方法,否则测试将失败
Read more about verify here.
在此处阅读有关验证的更多信息。
UPDATE
更新
Since your edited post states that you are using jMock, a quick googeling showed me that it is possible to achieve a similar behaviour with jMock and it's expect
method. It's used as below:
由于您编辑过的帖子指出您正在使用 jMock,因此快速的谷歌搜索向我展示了使用 jMock 及其expect
方法可以实现类似的行为。它的用法如下:
mockedObject.expects(once()).method("nameOfMethod").with( eq("An optional paramter") );
More detailed explanation can be found by reading jMocks getting started page.
可以通过阅读 jMocks入门页面找到更详细的解释。
回答by sanbhat
say you have a method child()
which is called in parent()
说你有一个child()
被调用的方法parent()
public void parent() {
child();
}
In child()
to get the last method it got invoked from, you can use StackTraceElement
在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;
}
}
}
回答by Humungus
If you are writing a mock object with the methods you want to check whether they were called, you can implement the methods in a way they raise some flag when they are called, for example
如果您正在使用要检查它们是否被调用的方法编写模拟对象,则可以以在调用时引发某些标志的方式来实现这些方法,例如
public void playHappyMusic() {
this.wasCalled = true;
}
wasCalled
being a public (or with getters) class variable. Then you just check the flag.
wasCalled
是一个公共(或使用 getter)类变量。然后你只需检查标志。
回答by Averroes
Provide you are in the same thread as the calling method, you can check the stack trace in any given moment this way:
如果您与调用方法在同一线程中,您可以通过以下方式在任何给定时刻检查堆栈跟踪:
Thread.currentThread().getStackTrace()
You can see what method are called doing it like this:
你可以看到什么方法被称为这样做:
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
System.out.println(ste);
}
For example:
例如:
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);
}
}
results in
结果是
java.lang.Thread.getStackTrace(Unknown Source)
Test.makeTest(Test.java:17)
Test.main(Test.java:11)