- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我在代码中的某处更改了一些方法,这本不应该导致任何奇怪的测试失败,但 JMock 似乎不这么认为。
我把这个问题归结为最少量的废话,看起来像这样:
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.lib.legacy.ClassImposteriser;
import org.junit.Test;
public class TestMocking {
@Test
public void test() {
Mockery mockery = new Mockery() {{
setImposteriser(ClassImposteriser.INSTANCE);
}};
final Owner owner = mockery.mock(Owner.class);
final RealThing thing = mockery.mock(RealThing.class, "thing");
mockery.checking(new Expectations() {{
oneOf(owner).getThing(); will(returnValue(thing));
oneOf(thing).method(); will(returnValue(Collections.emptyList()));
}});
owner.getThing().method();
mockery.assertIsSatisfied();
}
public static interface Owner {
BaseThing getThing();
}
public static interface BaseThing {
Collection<?> method();
}
public static interface RealThing extends BaseThing {
List<?> method();
}
}
(编辑:这现在使用了一个 ClassImposteriser,即使不再有类,因为我想证明你可以在没有那个冒名顶替者的情况下运行完全相同的代码并且测试将通过。)
运行结果:
unexpected invocation: thing.method()
expectations:
expected once, already invoked 1 time: owner.getThing(); returns <thing>
expected once, never invoked: thing.method(); returns <[]>
what happened before this:
owner.getThing()
好了,当从未调用预期的 thing.method() 时,“意外的”thing.method()。我以前曾在针对模拟对象测试多线程类时看到过这种情况,但这次它全部发生在单个线程中。就像 JMock 以某种方式从第一个方法调用返回一个不同的模拟对象,即使我没有模拟这样的对象。
如果我删除返回更具体类型的覆盖方法,那么它就会消失,但我显然不能那样做。同样,如果我删除 ClassImposteriser 的使用,问题就会消失,但我在实际测试中模拟的对象之一是其他人的类。我想我可以尝试在一个测试中使用两个 Mockery 实例,但除此之外我没有想法。
最佳答案
隐藏类(静态)方法与覆盖实例方法的工作方式并不完全相同。为了证明 JMock 不是这里的罪魁祸首,试试这个:
public class test3 {
public static void main(String[] args) {
Owner owner = new Owner();
owner.getThing().method(); //Like how you execute your test
RealThing thing = new RealThing();
thing.method(); //Similar to your mock.
}
private static class Owner {
private BaseThing thing = new RealThing();
public BaseThing getThing() {
return thing;
}
}
private static class BaseThing {
public static void method() {
System.out.println("Basething!");
}
}
private static class RealThing extends BaseThing {
public static void method() {
System.out.println("Realthing!");
}
}
}
请注意,对 method()
的两次调用打印不同的内容!两者都是 RealThing 的实例,但它们调用不同的方法。调用的静态方法取决于它是从子类调用还是从父类(super class)调用。在上面的第一个调用中,方法被声明为 BaseClass,因此调用了 BaseClass.method()
,即使它是 RealClass 的实例。对 method()
的第二次调用被声明为 RealClass,因此调用了 RealClass.method()
。
因此,JMock 的结果是有效的。调用的 method()
与您设置的预期不同。
不要对我对此的解释感到满意。请务必在此处阅读:http://docs.oracle.com/javase/tutorial/java/IandI/override.html
修复(支持 BaseThing.method()
),更改:
final RealThing thing = mockery.mock(RealThing.class, "thing");
收件人:
final BaseThing thing = mockery.mock(RealThing.class, "thing");
或者,如果您更喜欢使用 RealThing.method()
,请更改:
owner.getThing().method()
收件人:
RealThing thing = (RealThing)owner.getThing();
thing.method();
关于java - JMock "unexpected invocation"当相同的调用是 "expected once, never called",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13850687/
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我是脚本新手。如何编写 Expect 脚本以通过 ssh 连接到设备并提示用户输入密码?我们使用 pin + RSA token 代码作为密码,因此我无法存储密码。 #!/usr/bin/expect
我编写了以下代码并尝试执行它。但我在执行 do {”时遇到“无效的命令名称“do”” 代码: #!/usr/bin/expect set val 0; set input 5; do { pu
我已经查看了 Expect 联机帮助页并用 Google 搜索了它,但我还没有找到 expect 的 -r 是什么。我看到这个选项以前是这样用的 expect -r "\r\n\r\n" 在 expe
我的 shebang 看起来像这样: #!/usr/bin/expect -d 当我从命令行运行脚本时,它会提供我想要的内容。 但是,我通过 crontab 运行这个脚本。是否可以将调试开关保持打开状
我是 Expect 脚本的新手。 我在 Linux 机器上为 ssh 编写了一个 Expect 脚本,在那里我在 ssh 到不同的 Linux 机器时遇到了问题。下面我复制了脚本。 !/usr/loc
Scene 1, Layer 'script', Frame 1, Line 9 1084: Syntax error: expecting identifier before this. Sc
我正在运行调试命令以将命令的输出记录到文件中。我尝试了 log_file 命令,但它没有记录输出。我的代码如下: log_file -a gdb.txt send "~/debugulator.sh
我希望 expect_user 有一个无限的(或非常大的)超时和 expect 的默认超时。有没有办法设置不同的超时?或者我是否只需要在每次更改用途之前手动执行此操作? 最佳答案 expect 和ex
我正在学习 iOS 编程(我来自 Android),我正在寻找更容易获取字符串的方法。有了这个建议,我定义了下一个宏并在一些代码片段中使用它: #define STRING_BASE @"InfoPl
你好我是 rspec 的新手,我想弄清楚将 block 传递给 expect{} 和只使用 expect() 之间的区别 这是一个简单的例子 require "rails_helper" RSpec.
我正在尝试为 React JS 运行单元测试 - 使用 jest/enzyme。 目前测试失败。不太清楚为什么,也许我没有正确调用 expect(wrapper.find)。这是我测试的一部分: F
例如,现在我有一个“root.exp”期望脚本如下: spawn ssh user@ip expect "Password:" send "password" 然后,我要发送到这个ssh服务器的exp
您好,我是 Expect 脚本编写的新手,我一直在尝试使用以下方法将 IP 地址获取到变量中: set timeout -1 spawn $env(SHELL) match_max 100000 se
expect.anything() 不适用于 expect.toBe(),但适用于 expect.toEqual() test("this will pass", () => { expect("
我有一个如下所示的简单脚本,从命令行读取 2 个数字并将它们加在一起: $cat runexp.sh #!/bin/bash echo "read 1st number" read n1 echo "
当 Linux 机器的 $IP 登录后询问密码时,下面的 expect 脚本工作正常 但在某些情况下,某些Linux机器不需要ssh密码(我们可以不用密码登录), 所以我需要更改我的期望脚本以支持没有
我正在尝试使用 expect 远程登录服务器并更改用户密码。该应用程序要求,如果您要更改的密码包含特殊字符,则将其引用。问题是,还需要引用 expect send 语句,当我尝试将两者结合起来时,脚本
下面这个简单的 expect 脚本的目标是获取远程机器上的 hostname 名称 有时期望脚本无法执行到 $IP_ADDRESS 的 ssh(因为远程机器不活动等) 所以在这种情况下,expect
我试图创建一个宏来替换, first: Some(first.as_ref().parse::().expect("Could not parse 'first'")) 我在其他模块(如 Clap w
我是一名优秀的程序员,十分优秀!