我今天才开始了解Mockito.我写了一些简单的测试(使用JUnit,见下文),但我无法弄清楚如何在Spring的托管bean中使用模拟对象.使用Spring的最佳实践是什么?我应该如何向我的bean注入模拟依赖?
你可以跳过这个直到回到我的问题.
首先,我学到了什么.这是非常好的文章Mocks Are Not Stubs解释了基础知识(Mock的检查行为验证不是状态验证).然后有一个很好的例子Mockito 和这里更容易嘲笑mockito.我们有解释说Mockito的模拟对象都是模拟和存根.
这个测试
@Test
public void testReal(){
List<String> mockedList = mock(List.class);
//stubbing
//when(mockedList.get(0)).thenReturn("first");
mockedList.get(anyInt());
OngoingStubbing<String> stub= when(null);
stub.thenReturn("first");
//String res = mockedList.get(0);
//System.out.println(res);
//you can also verify using argument matcher
//verify(mockedList).get(anyInt());
verify(mockedList);
mockedList.get(anyInt());
}
Run Code Online (Sandbox Code Playgroud)
工作得很好.
回到我的问题.在这里注入Mockito模拟到Spring bean有人试图使用Springs ReflectionTestUtils.setField(),但是在这里Spring Integration Tests,创建模拟对象我们建议改变 Spring的上下文.
我真的不明白最后两个链接......有人可以向我解释一下Spring与Mockito有什么问题吗?这个解决方案有什么问题?
@InjectMocks
private MyTestObject testObject …Run Code Online (Sandbox Code Playgroud) 错误细节:
org.mockito.exceptions.misusing.WrongTypeOfReturnValue:
Boolean cannot be returned by updateItemAttributesByJuId()
updateItemAttributesByJuId() should return ResultRich
This exception might occur in wrongly written multi-threaded tests.
Please refer to Mockito FAQ on limitations of concurrency testing.
Run Code Online (Sandbox Code Playgroud)
我的代码:
@InjectMocks
protected ItemArrangeManager arrangeManagerSpy = spy(new ItemArrangeManagerImpl());
@Mock
protected JuItemWriteService juItemWriteService;
when(arrangeManagerSpy
.updateItemAttributes(mapCaptor.capture(), eq(juId), eq(itemTO.getSellerId())))
.thenReturn(false);
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,我呼吁when对updateItemAttributes(它返回boolean)不是updateItemAttributesByJuId.
boolean从updateItemAttributesByJuId?我有一个课程如下:
public class A {
public A(String test) {
bla bla bla
}
public String check() {
bla bla bla
}
}
Run Code Online (Sandbox Code Playgroud)
在构造函数中的逻辑A(String test)和check()是我试图嘲弄的事情.我想要任何调用:new A($$$any string$$$).check()返回一个虚拟字符串"test".
我试过了:
A a = mock(A.class);
when(a.check()).thenReturn("test");
String test = a.check(); // to this point, everything works. test shows as "tests"
whenNew(A.class).withArguments(Matchers.anyString()).thenReturn(rk);
// also tried:
//whenNew(A.class).withParameterTypes(String.class).withArguments(Matchers.anyString()).thenReturn(rk);
new A("random string").check(); // this doesn't work
Run Code Online (Sandbox Code Playgroud)
但它似乎没有奏效.new A($$$any string$$$).check()仍然通过构造函数逻辑而不是获取模拟对象A.
Mockito - 我理解间谍调用对象上的真实方法,而模拟调用double对象上的方法.除非有代码气味,否则应避免使用间谍.但是,间谍如何工作以及我何时应该使用它们?他们与嘲笑有什么不同?
似乎mockito只验证是否调用了模拟对象的方法,并且模拟对象总是具有某种功能.像doReturn().when(模拟对象)...
但我可以创建一个模拟对象并定义doReturn().when(模拟对象)..然后验证另一个对象的方法被调用?
这就是我想要做的:我定义一个mockEnvironment并返回一个响应,无论发生什么.但后来我想验证在不同情况下调用anotherObj的不同方法.
怎么做?
public class BaseClass {
private Environment mockEnvironment;
@Test
public void testcase () {
setMockitoEnvironment();
response = foo(mockEnvironment, argument1);
verify(anotherObj).codePath1(...);
response = foo(mockEnvironment, argument2);
verify(anotherObj).codePath2(...);
}
}
//this method successfully return a response with any input
//because I do not care how response is eventually generated,
//I only care whether code path reaches createResponse() via
//code path 1 or code path 2.
private void setMockitoEnvironment() {
mockEnvironment = mock(Environment.class);
doReturn (response).when(mockEnvironment).createResponse(for any input);
}
private Response foo(...) …Run Code Online (Sandbox Code Playgroud) 我没有运气让Mockito捕获函数参数值!我正在嘲笑搜索引擎索引而不是构建索引,我只是使用哈希.
// Fake index for solr
Hashmap<Integer,Document> fakeIndex;
// Add a document 666 to the fakeIndex
SolrIndexReader reader = Mockito.mock(SolrIndexReader.class);
// Give the reader access to the fake index
Mockito.when(reader.document(666)).thenReturn(document(fakeIndex(666))
Run Code Online (Sandbox Code Playgroud)
我不能使用任意参数,因为我正在测试查询的结果(即他们返回哪些文档).同样,我不想为每个文档指定一个特定的值并且有一行!
Mockito.when(reader.document(0)).thenReturn(document(fakeIndex(0))
Mockito.when(reader.document(1)).thenReturn(document(fakeIndex(1))
....
Mockito.when(reader.document(n)).thenReturn(document(fakeIndex(n))
Run Code Online (Sandbox Code Playgroud)
我查看了使用Mockito页面上的回调部分.不幸的是,它不是Java,我无法用Java自己解释它.
编辑(澄清):如何让Mockito获取参数X并将其传递给我的函数?我想要传递给函数的X的确切值(或ref).
我不想枚举所有情况,并且任意参数将不起作用,因为我正在测试不同查询的不同结果.
Mockito页面说
val mockedList = mock[List[String]]
mockedList.get(anyInt) answers { i => "The parameter is " + i.toString }
Run Code Online (Sandbox Code Playgroud)
这不是java,我不知道如何转换成java或传递给函数发生的事情.
我试图穿过我和Mockito之间的砖墙.为了获得Mockito东西的正确导入静态语句,我已经把头发撕掉了.你认为有人会抛出一张桌子,说anyInt()来自org.mockito.Matchers,而when()来自org.mockito.Mockito等,但这对新手来说太有帮助了,不是吗?
这种事情,特别是当与无数更多以星号结尾的import语句混合在一起时,并不总是非常有用:
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
Run Code Online (Sandbox Code Playgroud)
是的,我知道并且一直在尝试使用Eclipse Window - > Preferences-> Java - > Editor-> Content Assist - > Favorites机制.它有所帮助,但它并没有击中头部.
任何对这个问题的答案都将不胜感激.
非常感谢,Russ
我正在测试一个带有预期异常的方法.我还需要验证在抛出异常之后调用了一些清理代码(在模拟对象上),但看起来忽略了验证.这是代码.我正在使用Junit ExpectedException Rule来验证预期的异常.
@Rule
public ExpectedException expectedEx = ExpectedException.none();
@Test
public void testExpectedException()
{
MockedObject mockObj = mock(MockedObj.class);
MySubject subject = new MySubject(mockedObj);
expectedEx.expect(MyException.class);
expectedEx.expectMessage("My exception message.");
subject.someMethodThrowingException();
verify(mockObj).
someCleanup(eq(...));
}
Run Code Online (Sandbox Code Playgroud)
似乎verify完全被忽视了.无论我放入什么方法verify,我的测试都是通过,这不是我想要的.
知道为什么会这样吗?
一旦测试开始,我就会遇到以下异常:
Testcase: treeCtorArgumentTest(com.xythos.client.drive.cachedtree.CachedTreeTest): Caused an ERROR
Could not initialize plugin: interface org.mockito.plugins.MockMaker
java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.MockMaker
at org.mockito.internal.configuration.plugins.PluginLoader$1.invoke(PluginLoader.java:66)
at com.sun.proxy.$Proxy7.isTypeMockable(Unknown Source)
at org.mockito.internal.util.MockUtil.typeMockabilityOf(MockUtil.java:29)
at org.mockito.internal.util.MockCreationValidator.validateType(MockCreationValidator.java:22)
at org.mockito.internal.creation.MockSettingsImpl.validatedSettings(MockSettingsImpl.java:168)
at org.mockito.internal.creation.MockSettingsImpl.confirm(MockSettingsImpl.java:162)
at org.mockito.internal.MockitoCore.mock(MockitoCore.java:64)
at org.mockito.Mockito.mock(Mockito.java:1687)
at org.mockito.Mockito.mock(Mockito.java:1600)
at com.xythos.client.drive.cachedtree.CachedTreeTest.setUp(CachedTreeTest.java:51)
Caused by: java.lang.NoClassDefFoundError: net/bytebuddy/dynamic/loading/ClassLoadingStrategy
at org.mockito.internal.creation.bytebuddy.SubclassByteBuddyMockMaker.<init>(SubclassByteBuddyMockMaker.java:33)
at org.mockito.internal.creation.bytebuddy.ByteBuddyMockMaker.<init>(ByteBuddyMockMaker.java:22)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.lang.Class.newInstance(Class.java:442)
at org.mockito.internal.configuration.plugins.PluginLoader.loadPlugin(PluginLoader.java:54)
at org.mockito.internal.configuration.plugins.PluginRegistry.<init>(PluginRegistry.java:18)
at org.mockito.internal.configuration.plugins.Plugins.<clinit>(Plugins.java:17)
at org.mockito.internal.util.MockUtil.<clinit>(MockUtil.java:24)
Caused by: java.lang.ClassNotFoundException: net.bytebuddy.dynamic.loading.ClassLoadingStrategy
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
Run Code Online (Sandbox Code Playgroud)
这是我的测试:
package com.xythos.client.drive.cachedtree;
import org.junit.After;
import org.junit.AfterClass;
import …Run Code Online (Sandbox Code Playgroud) 我如何模拟正在内联初始化的字段变量?
例如
class Test {
private Person person = new Person();
...
public void testMethod() {
person.someMethod();
...
}
}
Run Code Online (Sandbox Code Playgroud)
在这里,我想在测试方法时测试person.someMethod() - Test#testMethod.
我需要模拟person变量的初始化.任何线索?
编辑:我不允许修改Person类.
mockito ×10
java ×9
unit-testing ×3
junit ×2
mocking ×2
junit-rule ×1
junit4 ×1
powermock ×1
powermockito ×1
spring ×1
spy ×1