是否有可能以通用方式拦截模拟上的所有方法调用?
例
给定供应商提供的类如:
public class VendorObject {
public int someIntMethod() {
// ...
}
public String someStringMethod() {
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
我想创建一个模拟,将所有方法调用重定向到另一个具有匹配方法签名的类:
public class RedirectedToObject {
public int someIntMethod() {
// Accepts re-direct
}
}
Run Code Online (Sandbox Code Playgroud)
Mockito中的when().thenAnswer()构造似乎符合要求,但我无法找到一种方法来匹配任何方法调用与任何args.无论如何,InvocationOnMock肯定会给我所有这些细节.有没有通用的方法来做到这一点?看起来像这样的东西,其中when(vo.*)被适当的代码替换:
VendorObject vo = mock(VendorObject.class);
when(vo.anyMethod(anyArgs)).thenAnswer(
new Answer() {
@Override
public Object answer(InvocationOnMock invocation) {
// 1. Check if method exists on RedirectToObject.
// 2a. If it does, call the method with the args and return the result.
// 2b. If it …Run Code Online (Sandbox Code Playgroud) 在BundleProcessorTest.java中的以下两个测试用例中,我得到的是异常,但是,我的第一个测试用例成功通过了.
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:此处检测到错位的参数匹配器:
- > at bundle.test.BundleProcessorTest.bundlePluginShouldNotBeNull(BundleProcessorTest.java:22)
您不能在验证或存根之外使用参数匹配器.正确使用参数匹配器的示例:when(mock.get(anyInt())).thenReturn(null); doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject()); 验证(模拟).someMethod(包含( "富"))
此外,此错误可能会显示,因为您使用参数匹配器与无法模拟的方法.以下方法无法进行存根/验证:final/private/equals()/ hashCode().
at the package.test.BundleProcessorTest.bundlePluginCollectionShouldNotBeNull(BundleProcessorTest.java:28)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
请在下面找到简化的代码清单: -
BundlePlugin.java
package bundle;
import java.util.List;
public class BundlePlugin {
private final String pluginName ;
private final List<String> featureContent ;
public BundlePlugin(String pluginName, List<String> featureContent) {
super();
this.pluginName = pluginName;
this.featureContent = featureContent;
}
public String getPluginName() {
return pluginName;
}
public List<String> getFeatureContent() {
return featureContent;
}
}
Run Code Online (Sandbox Code Playgroud)
BundleProcessor.java
package bundle;
import java.util.ArrayList;
import …Run Code Online (Sandbox Code Playgroud) 我的测试中有一行目前看起来像:
Mockito.verify(mockMyObject).myMethod(Mockito.contains("apple"));
Run Code Online (Sandbox Code Playgroud)
我想修改它以检查参数是否包含"apple"和"banana".我该怎么做?
假设我有以下psuedo测试代码:
//Let's import Mockito statically so that the code looks clearer
import static org.mockito.Mockito.*;
//mock creation
List mockedList = mock(List.class);
//using mock object
mockedList.add("one");
mockedList.clear();
//what do these two verify methods do ?
verify(mockedList).add("one");
verify(mockedList).clear();
Run Code Online (Sandbox Code Playgroud)
我一直在显示测试通过,但我不知道验证意味着什么?什么是确切的验证?我知道我嘲笑了一个添加和清除的调用,但这两个验证调用有什么作用?
我有一个接口与以下方法
public interface IRemoteStore {
<T> Optional<T> get(String cacheName, String key, String ... rest);
}
Run Code Online (Sandbox Code Playgroud)
实现接口的类的实例称为remoteStore.
当我用mockito模拟它并在以下时使用该方法:
Mockito.when(remoteStore.get("a", "b")).thenReturn("lol");
Run Code Online (Sandbox Code Playgroud)
我收到错误:
无法解析方法'thenReturn(java.lang.String)'
我认为这与get返回Optional类的实例这一事实有关,所以我尝试了这个:
Mockito.<Optional<String>>when(remoteStore.get("cache-name", "cache-key")).thenReturn
(Optional.of("lol"));
Run Code Online (Sandbox Code Playgroud)
但是,我得到了这个错误:
当Mockito中的(可选'<'String'>')无法应用于(可选'<'对象'>')时.
它唯一有效的时间是:
String returnCacheValueString = "lol";
Optional<Object> returnCacheValue = Optional.of((Object) returnCacheValueString);
Mockito.<Optional<Object>>when(remotestore.get("cache-name", "cache-key")).thenReturn(returnCacheValue);
Run Code Online (Sandbox Code Playgroud)
但上面返回一个Optional'<'Object'>'的实例,而不是Optional'<'String'>.
为什么我不能直接返回Optional'<'String'>'的实例?如果可以,我该怎么做呢?
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.verify;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
public class MockitoTest {
public static class TestMock {
public void doIt(String s) {
}
}
public static void main(String[] args) {
TestMock mock = Mockito.mock(TestMock.class);
mock.doIt("1");
mock.doIt("2");
ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);
verify(mock, atLeastOnce()).doIt(argument.capture());
System.out.println(argument.getValue());
verify(mock, atLeastOnce()).doIt(argument.capture());
System.out.println(argument.getValue());
}
}
Run Code Online (Sandbox Code Playgroud)
我希望这打印,1 2但它打印2 2.似乎'1'调用丢失了.有没有办法可以验证验证是否发生了1然后2呢?
给出一个Kotlin单例对象和一个称之为方法的乐趣
object SomeObject {
fun someFun() {}
}
fun callerFun() {
SomeObject.someFun()
}
Run Code Online (Sandbox Code Playgroud)
有没有办法模拟电话SomeObject.someFun()?
在我正在进行的项目中,我经常在一个领域看到@Spy并@InjectMocks一起使用.但我从未在任何教程或其他资源中看到过这种方式.我在谷歌搜索了这个特定的组合,但除了GitHub上的这个帖子之外没有找到任何其他内容:https:
//github.com/mockito/mockito/issues/169
这让我觉得我们正在以一种奇怪的方式使用它.
注意:我认为同时使用两个注释的原因有时是因为如果您只使用@InjectMocksMockito尝试使用no-args构造函数实例化该类.但是如果没有no-args构造@Spy函数并添加,则可以使用该对象而无需空构造函数.
编辑:另一个重要用途是,如果只使用两个注释,则只能存根方法.
我正在尝试验证java.sql.DriverManager.getConnection使用JUnit,Mockito和PowerMock 的调用.
这是我的测试用例:
@RunWith(PowerMockRunner.class)
@PrepareForTest(DriverManager.class)
public class MySQLDatabaseConnectionFactoryTest {
private ConfigurationService configurationService;
private MySQLDatabaseConnectionFactory reference;
@Before
public void setUp() throws Exception {
this.reference = new MySQLDatabaseConnectionFactory();
}
@Test
public void testGetConnection() throws SQLException {
// setup
Connection connection = mock(Connection.class);
PowerMockito.mockStatic(DriverManager.class);
when(DriverManager.getConnection(anyString(), anyString(), anyString())).thenReturn(connection);
// run
this.reference.getConnection();
// verify
PowerMockito.verifyStatic();
DriverManager.getConnection("jdbc:mysql://myhost:1111/database", "username", "password");
}
}
Run Code Online (Sandbox Code Playgroud)
这是测试中的代码:
public class MySQLDatabaseConnectionFactory implements
DatabaseConnectionFactory {
@Override
public Connection getConnection(IApplicationInstance appInstance) {
try {
return DriverManager.getConnection(String.format("jdbc:mysql://%s:%d/%s",
MYSQL_HOST, MYSQL_PORT, MYSQL_DATABASE), MYSQL_USERNAME, MYSQL_PASSWORD);
} …Run Code Online (Sandbox Code Playgroud) 我想用签名模拟一个方法:
public <T> T documentToPojo(Document mongoDoc, Class<T> clazz)
Run Code Online (Sandbox Code Playgroud)
我嘲笑它如下:
Mockito.when(mongoUtil.documentToPojo(Mockito.any(Document.class), Mockito.any(WorkItemDTO.class)))
Run Code Online (Sandbox Code Playgroud)
但我得到的错误是:
documentToPojo(Document, Class<T>)类型中的方法MongoUtil不适用于参数(Document, WorkItemDTO)
Mockito有什么方法可以帮我模拟T吗?
mockito ×10
java ×8
unit-testing ×6
mocking ×3
junit ×2
powermock ×2
android ×1
kotlin ×1
mongodb-java ×1
optional ×1
powermockito ×1