[英]mockito.AdditionalAnswers.returnsFirstArg() for overloaded methods
I have a problem with returnsFirstArg
for overloaded methods, where the firstArg
is not nessessarily the same type as the return type. 对于重载的方法,
returnsFirstArg
存在问题,其中firstArg
的类型不一定与返回类型相同。
key
key
的值 Is there anyway to achieve this and get these Tests green? 无论如何,要实现这一目标并使这些测试达到绿色?
This is a minimum NOT working example, in real live Translator is more complex and can't be modified. 这是一个最低的NOT正常工作示例,在实际的Live Translator中更为复杂,无法修改。
package test;
import static org.hamcrest.Matchers.is;
import static org.mockito.Mockito.mock;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.AdditionalAnswers.returnsFirstArg;
import java.util.Locale;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class TranslatorTest {
private class Translator {
String getText(final String key) {
return "translated " + key;
}
String getText(final Locale locale, final String key) {
return "translated " + key + " for locale " + locale;
}
}
@Test
public void test_withoutToString() throws Exception {
final String key = "com.stackoverflow.translator.label";
Translator translator = mock(Translator.class, returnsFirstArg());
assertThat(translator.getText(key), is(key));
final Locale locale = new Locale("en_GB"); // java.lang.ClassCastException: java.util.Locale cannot be cast to java.lang.String
assertThat(translator.getText(locale, key), is(key));
}
@Test
public void test_withToString() throws Exception {
final String key = "com.stackoverflow.translator.label";
Translator translator = mock(Translator.class, returnsFirstArg().toString());
assertThat(translator.getText(key), is(key));
/*
* java.lang.AssertionError:
* Expected: is "com.stackoverflow.translator.label"
* but: was null
*/
final Locale locale = new Locale("en_GB");
assertThat(translator.getText(locale, key), is(key));
}
}
I wouldn't bend over backwards to try to define some generic default behavior when creating the mock object. 创建模拟对象时,我不会弯腰尝试定义一些通用的默认行为。 You have two different methods, and could just specify two different behaviors explicitly:
您有两种不同的方法,可以只明确指定两种不同的行为:
@Before
public void setUp() {
translator = mock(Translator.class);
when(translator.getText(any(), any()))
.thenAnswer(AdditionalAnswers.returnsSecondArg());
when(translator.getText(any()))
.thenAnswer(AdditionalAnswers.returnsFirstArg());
}
EDIT: 编辑:
Addressing the added/clarified requirement in the comments could be problematic, unless you have a good way to recognize argument you want to return. 解决注释中添加/阐明的要求可能会遇到问题,除非您有一种很好的方法来识别要返回的参数。
Assuming you can use some straight-forward logic, like returning the first string argument, you could implement your own Answer
: 假设您可以使用一些简单的逻辑,例如返回第一个字符串参数,则可以实现自己的
Answer
:
Answer<Object> returnsFirstString =
invocationOnMock -> Arrays.stream(invocationOnMock.getArguments())
.filter(String.class::isInstance)
.findFirst()
.orElse(null);
translator = mock(Translator.class, returnsFirstString);
This can, of course, be refined with some different logic like applying to getText
methods only, etc. 当然,这可以使用一些不同的逻辑来完善,例如仅应用于
getText
方法,等等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.