我有以下代码:
private MyService myService;
@Before
public void setDependencies() {
myService = Mockito.mock(MyService.class, new StandardServiceAnswer());
Mockito.when(myService.mobileMethod(Mockito.any(MobileCommand.class), Mockito.any(Context.class)))
.thenAnswer(new MobileServiceAnswer());
}
我的意图是所有对mockedmyService
的调用都应该以标准方式应答。但是对Mobile e方法
(这是公共的)的调用应该以特定的方式应答。
我发现,当我添加对< code>mobileMethod调用的应答时,不是附加< code>MobileServiceAnswer,Java实际上是调用< code > my service . mobile method ,这导致了NPE。
这可能吗?似乎应该可以覆盖默认答案。如果可能,正确的方法是什么?
以下是我的< code >答案:
private class StandardServiceAnswer implements Answer<Result> {
public Result answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
Command command = (Command) args[0];
command.setState(State.TRY);
Result result = new Result();
result.setState(State.TRY);
return result;
}
}
private class MobileServiceAnswer implements Answer<MobileResult> {
public MobileResult answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
MobileCommand command = (MobileCommand) args[0];
command.setState(State.TRY);
MobileResult result = new MobileResult();
result.setState(State.TRY);
return result;
}
}
你想做的是有效的,当我做的时候,它是有效的:
private Properties props;
@Before
public void setUp() {
props = mock(Properties.class, new Answer<String>() {
@Override
public String answer(InvocationOnMock invocation) throws Throwable {
return "foo";
}
} );
when(props.get("override")).thenAnswer(new Answer<String>() {
@Override
public String answer(InvocationOnMock invocation) throws Throwable {
return "bar";
}
} );
}
@Test
public void test() {
assertEquals("foo", props.get("no override"));
assertEquals("bar", props.get("override"));
}
因此,使用调试器逐步执行测试用例,找出您所做的与这个简单用例不同的事情。
两个不相关的意外一起导致了这个问题:
>
Mockito.any(class)
实际上并不返回该类的对象。它返回null
并将“忽略参数并接受任何内容”匹配器隐藏在一个名为ArgumentMatcher存储的秘密内部匹配器堆栈上。该参数值实际上为空,但在大多数情况下您不会看到它。
语句当(foo.bar()). then返回(baz)
实际上总是调用foo.bar()
。通常这没有副作用——尤其是当你正在存根它的第一个动作链时——所以你不会注意到它。
在存根期间,Java调用您的真实答案,并尝试在您的基于matcher的(空)参数上调用setState
。根据Java评估顺序,这是有意义的:Mockito调用您的答案,就好像它是正在测试的系统调用您的答案一样,因为Mockito不可能知道当时,对移动方法
的调用立即先于对的调用。它还没有到达那里。
答案是使用“doVerb”方法,例如
do的回答
,do返回
,和doThrow
,我喜欢称之为“尤达语法”。因为这些包含当(对象).方法()
而不是当(object.method())
,Mockito有机会停用您之前设置的期望,并且您的原始答案永远不会被触发。它看起来像这样:
MyService myService = Mockito.mock(MyService.class, new StandardServiceAnswer());
Mockito.doAnswer(new MobileServiceAnswer())
.when(myService).mobileMethod(
Mockito.any(MobileCommand.class), Mockito.any(Context.class));
值得注意的是,异常是您的覆盖不起作用的唯一原因。在正常情况下,“当时-thenVerb”完全可以覆盖,并且会回溯上一个操作,以免丢弃连续的操作,如
. then的返回(…). thenThrow(…)
。还值得注意的是,当(移动方法(命令,上下文))
会在存根期间更改命令
和上下文
而不会引发异常,这可能会引入微妙的测试空白。
一些开发人员甚至在任何时候都更喜欢“doVerb-when”语法而不是“when-thenVerb”语法,因为它具有从不调用其他mock的良好行为。欢迎你得出同样的结论——“doVerb”在“thenVerb”做的时候做所有事情,但在模拟和间谍中重写行为时更安全。我自己更喜欢“when”语法,它读起来有点好,而且它确实会检查返回值,只要你记住有时“doVerb”是到达你需要的地方的唯一方法。
我有一个RESTAPI,我不想强迫客户端发送请求参数。我有将近400个api方法,我不想将所有参数设置为“required=false” 我想覆盖Spring RequestParam的默认行为。我想将RequestParam接口的“required”属性的默认值设置为“false”。 有什么方法可以覆盖它吗?如果我不能或这不是最佳实践,有什么方法可以解决上述问题。
问题内容: 我已经能够覆盖所有名称以“ android:”为前缀的主题,但是Android themes.xml还定义了似乎无法被覆盖的属性。例如: colorTheground是在Theme.Light xml中定义的,但是在此处添加它可以使我 错误。如何为整个应用程序覆盖该样式? 问题答案: 您可以用修改属性(如)的方式覆盖标准属性,只是不要忘记添加如下前缀:
问题内容: 我想覆盖Java外观。我只想显示不同的按钮。 我想要Windows Look and Feel的所有功能,但仅按钮有所不同。希望你明白我的意思。 还告诉我如何制作圆形的JtabbedPane ??? 问题答案: 自定义GUI类 调用您的自定义GUI类
问题内容: 我有一个模板与此: Django自动将此翻译为Terminarsesión西班牙语。但是,我想将其翻译为Cerrarsesión。 我试图将此文字添加到.po文件中,但是在编译消息时出现错误,指出该文字重复。 有没有一种方法可以更改/覆盖默认的Django翻译? 谢谢。 问题答案: 最简单的方法是收集在django.contrib.admin语言环境文件夹中找到的.po文件,然后重新编
我目前正在做一个项目,在这个项目中,我们有一个jenkins实例与一个单独的网站并排运行,工作流程是这样的,用户需要点击网站中的链接,从而触发jenkins实例中的jenkins作业。 触发的jenkins作业有几十个参数,我们目前正在做的是,该网站将使用javascript构建一个如下URL: https://JENKINS_HOST/作业/JOB_NAME/build with Paramet
当它调用其他eureka客户机时使用feign。然而,当注册到eureka服务器时,它并不费力。我检查了源代码,发现eureka discovery客户端使用了jersey,jersey调用了http apache客户端。问题是,它使用了SchemeRegistryFactory.createDefault(),它将最终调用SSLContexts.createDefault(),后者不会考虑系统属