我有以下要测试的代码:
public class MessageService {
private MessageDAO dao;
public void acceptFromOffice(Message message) {
message.setStatus(0);
dao.makePersistent(message);
message.setStatus(1);
dao.makePersistent(message);
}
public void setDao (MessageDAO mD) { this.dao = mD; }
}
public class Message {
private int status;
public int getStatus () { return status; }
public void setStatus (int s) { this.status = s; }
public boolean equals (Object o) { return status == ((Message) o).status; }
public int hashCode () { return status; }
}
Run Code Online (Sandbox Code Playgroud)
我需要验证,该方法acceptFromOffice确实将状态设置为0,而不是持久消息,然后将其状态设置为1,然后再次保留它.
有了Mockito,我试图做以下事情:
@Test
public void …Run Code Online (Sandbox Code Playgroud) 像许多其他人一样,我很高兴听到Mockito现在可以使用Android并按照本教程亲眼看到它.一切似乎都是扇动的,我开始将模拟解决方案纳入我的Android测试项目...
然而,在建立我的应用程序的测试项目,以充分利用mockito-all-1.9.5,dexmaker-1.0而且dexmaker-mockito-1.0罐子我遇到一个问题,我的第一个测试案例.事实上恰恰是这个问题.我想要帮助的部分是;
Caused by: java.lang.VerifyError: org/mockito/cglib/core/ReflectUtils
at org.mockito.cglib.core.KeyFactory$Generator.generateClass(KeyFactory.java:167)
at org.mockito.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at org.mockito.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:217)
at org.mockito.cglib.core.KeyFactory$Generator.create(KeyFactory.java:145)
at org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:117)
at org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:109)
at org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:105)
at org.mockito.cglib.proxy.Enhancer.<clinit>(Enhancer.java:70)
Run Code Online (Sandbox Code Playgroud)
我被告知这个"还没有完全奏效",因为堆栈跟踪意味着没有使用DexMaker jar - 引用此响应.但是,我怀疑我在项目设置方面做错了所以我想从这里的集体知识库中抽取来看看这确实是用户错误还是beta-bug.
请在下面找到我的测试项目配置的屏幕截图.该项目是通过Android向导创建的,除了在目录下包含Mockito和DexMaker jar(如上所述)之外,没有共享任何特殊功能libs.

不要介意测试内容(测试在执行单元测试之前失败),设置如下所述;
public class TestSpotRatingCalculator extends InstrumentationTestCase {
@Mock
private AService aService; // Changed the service names being used here - not important.
@Mock
private BService bService;
@Mock
private CService cService;
@Mock
private DService …Run Code Online (Sandbox Code Playgroud) 我一直在阅读有关参数捕获者的内容,我读的越多,我就越迷失.有人可以用一个例子解释它的痛苦吗?
pom.xml为了让PowerMock与Mockito合作,我需要添加哪些罐子?我有以下依赖项:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-support</artifactId>
<version>1.4.11</version>
<scope>test</scope>
</dependency>
Run Code Online (Sandbox Code Playgroud)
但是当我@PrepareForTest在类级别添加注释时,Eclipse无法找到它,但它可以找到PowerMockito.我错过了什么罐子?
如果没有在您正在测试的类中创建/初始化模拟对象,它是如何在运行时获取模拟对象的,它不是静态的(单例模式),或者您没有某种类型的测试构造函数可以挂钩?
在我正在编写单元测试的类中,我遇到了一个我尚未遇到/解决过的场景.我有一个JMS资源(QueueConnectionFactory供参考,但它没关系),这是我正在测试的类的私有变量.由于它具有javax.annotation.Resource注释,因此在运行时假定它是可用的.在测试期间,它不是,这就需要模拟这个对象.
它不是一个静态类,并没有以静态方式使用,如果它是我可以轻松地使用我遇到的各种静态模拟方法进行模拟.由于资源永远不会在本地创建(在构造函数中或甚至在测试构造函数中),因此我无法传入Mock对象,因此在测试的运行时,将使用mock而不是实际的对象.如何模拟此资源,以便在测试执行时,它将用于代替@Resource我正在测试的类中的私有对象?
作为参考,代码调用createConnection()在QueueConnectionFactory其中抛出一个空指针异常,因为该工厂尚未初始化/嘲笑.
@Stateless
public class Example{
@Resource(name = "jms/exampleQCF")
private QueueConnectionFactory queueFactory;
...
public void testMe(){
Connection connection = queueFactory.createConnection();
...
}
}
Run Code Online (Sandbox Code Playgroud) ServiceCaller我想测试的Java类(调用)有这个:
@Autowired @Qualifier(value="serviceA")
SomeService serviceA;
@Autowired @Qualifier(value="serviceB")
SomeService serviceB;
Run Code Online (Sandbox Code Playgroud)
(有一种doWork()方法可以检查条件并调用A或B).
如何将每个服务的模拟注入适当的变量?
我的Junit有这个:
@InjectMocks ServiceCaller classUnderTest = new ServiceCaller();
@Mock SomeService mockServiceA;
@Mock SomeService mockServiceB;
Run Code Online (Sandbox Code Playgroud)
然而,当我运行我的测试以检查在正确条件下调用的服务A/B时,我得到空指针,因为没有注入模拟.
显然它是因为对同一个接口的多重依赖(SomeService).有没有办法在声明模拟服务时指定限定符?或者我是否需要为依赖项设置setter并设置旧的方式?
我正在尝试验证我正在测试的类调用正确的依赖类的方法.所以我试图匹配方法参数,但我并不真正关心这个测试中的实际值,因为我不想让我的测试变脆.
但是,我遇到了麻烦,因为Mockito决定我期待的行为是一个错误:https://github.com/mockito/mockito/issues/134
那么为可能为null的参数定义匹配器的正确方法是什么?
问题#134"已修复",此代码失败,因为匹配器仅在第一种情况下匹配.如何在所有4种情况下定义匹配器?
MyClass c = mock(MyClass.class);
c.foo("hello", "world");
c.foo("hello", null);
c.foo(null, "world");
c.foo(null, null);
verify(c, times(4)).foo(anyString(), anyString());
Run Code Online (Sandbox Code Playgroud) 当使用Mockito 1.9.x时,我一直Whitebox用来设置字段值以"注入"模拟.以下示例:
@Before
public void setUp() {
eventHandler = new ProcessEventHandler();
securityService = new SecurityServiceMock();
registrationService = mock(RegistrationService.class);
Whitebox.setInternalState(eventHandler, "registrationService", registrationService);
Whitebox.setInternalState(eventHandler, "securityService", securityService);
}
Run Code Online (Sandbox Code Playgroud)
我真的很喜欢这种方法,但是现在我尝试升级到Mockito 2.2.7我注意到(或者更确切地说,我的IDE注意并告诉了我很多次),在Mockito中找不到Whitebox.
我找到了一个可以替代的替代方案,也就是说 org.powermock.reflect.Whitebox,问题在于我得到另一个依赖(Powermock),只是为了使用Whitebox.
Powermock还有一个名为的类Whitebox,但遗憾的是它看起来好像不能用Mockito 2.2.x
Mockito有什么好的替代方案可以用来手动"注入"字段,现在Whitebox已经不再可用了吗?
我在回复@JeffBowman的帖子时写了一篇评论.简而言之,我选择复制WhiteBox的代码,并使用它,因为它在大多数测试用例中使用,并且该类与其他类没有依赖关系.这是解决这个问题的最快途径.
注意 @bcody建议的解决方案是一个更好的选择,如果你使用spring,它不会为你维护额外的代码.我得到的信息很晚了:(
我想测试以下方法:
public void dispatchMessage(MessageHandler handler, String argument1, String argument2, Long argument3) {
handler.registerMessage(() -> {
dispatcher.dispatch(argument1,
argument2,
argument3);
});
}
Run Code Online (Sandbox Code Playgroud)
MessageHandler辅助类在哪里将接受lambda形式的功能接口实现,并将其存储以供以后执行.
有没有办法验证mockito 已使用特定的lambda表达式调用dispatchMessagemocked 的方法MessageHandler:
意思是,我可以写一个这样的测试:
@Test
public void testDispatchMessage_Success() throws Exception {
myMessageDispatcher.dispatchMessage(handler, "activityId", "ctxId", 1l, );
verify(handler, times(1)).dispatchMessage(() -> {
dispatcher
.dispatch("activityId", "ctxId", 1l,);
});
}
}
Run Code Online (Sandbox Code Playgroud)
此测试将导致断言错误:参数不同!通缉:
......Tests$$Lambda$28/379645464@48f278eb
Run Code Online (Sandbox Code Playgroud)
实际调用有不同的参数:
..........Lambda$27/482052083@2f217633
Run Code Online (Sandbox Code Playgroud)
这是有道理的,因为mockito试图比较功能接口的两个不同实现,它们具有不同的哈希码.
那么有没有其他方法来验证该方法dispatchMessage()是否已使用返回void的lambda调用,并且body方法为
dispatcher.dispatch("activityId", "ctxId", 1l,);?
我刚刚迁移到JDK 11以使用最新的Java LTS版本.如果我将Eclipse中的执行JRE从10更改为11(并且只有那时),当我尝试运行我的测试时,我得到以下异常堆栈跟踪.
请注意,如果我切换回jdk-10,一切都按预期工作.我使用Spring Boot,我的测试也使用Mockito.我的pom.xml也在这里显示.
Spring Boot和/或Mockito与jdk-11之间是否存在已知的不兼容性?也许pom.xml中缺少另一个引用?
pom.xml中:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.0.1</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-model</artifactId>
<version>3.5.4</version>
</dependency>
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<!-- update Hibernate dependency on Javassist to 3.23.1 for Java 11 compatibility -->
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.23.1-GA</version>
</dependency>
</dependencies> …Run Code Online (Sandbox Code Playgroud)