Java 如何模拟属于JPA库的方法
我想模拟对以下方法toXml进行JUnit测试:Java 如何模拟属于JPA库的方法,java,jpa,junit,mockito,Java,Jpa,Junit,Mockito,我想模拟对以下方法toXml进行JUnit测试: void toXml(Object obj){ ByteArrayOutputStream out = null; try{ JAXBContext ctx = getContext(obj.getClass()); Marshaller marshaller = ctx.createMarshaller();
void toXml(Object obj){
ByteArrayOutputStream out = null;
try{
JAXBContext ctx = getContext(obj.getClass());
Marshaller marshaller = ctx.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
marshaller.setAttachmentMarshaller(new AttachmentMarshallerImpl());
out = new ByteArrayOutputStream();
marshaller.marshal( obj, out );
}catch( JAXBException e ){
throw new RuntimeException("Problem in parsing", e);
}
}
我尝试了以下方法:
@Test
public void testToXml() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
SystemPointDto systemPointDto = new SystemPointDto();
verify((marshaller), atLeast(1)).marshal(systemPointDto, out);
}
然而,当我运行测试时,我得到了一个NullPointerException。我是个测试新手,答案可能很简单。你能给我一些建议吗?提前谢谢
编辑:
评论中提出的模拟代码是:
@Mock
AttachmentMarshallerImpl attachmentMarshaller;
@InjectMocks
Marshaller marshaller;
这是堆栈跟踪:
initMocks(TestingIfTheMarshalGetsCalledWithoutExceptionTest.java:34)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
Caused by: org.mockito.exceptions.base.MockitoException: the type 'Marshaller' is an interface.
... 32 more
在您的方法中,可以从
JAXBContext
获取Marshaller
。要使用mock Marshaller,需要一个JAXBContext,在调用createMarshaller
时返回mock
假设以下测试类别:
public class XmlMarshaller {
private JAXBContextFactory contextFactory;
public XmlMarshaller(JAXBContextFactory contextFactory) {
this.contextFactory = contextFactory;
}
private JAXBContext getContext(Class<?> type) {
return contextFactory.get(type);
}
public void toXml(Object obj){
// ... your code
}
}
你在哪里嘲笑元帅?堆栈跟踪是什么?您可以发布模拟代码吗?@geo并且您要求的模拟代码已经发布。您是在测试中使用@RunWith(MockitoJUnitRunner.class)还是使用MockitoAnnotations.initMocks(this)?如果您没有使用这些注释中的任何一个,那么也可以尝试将@Mock注释添加到Marshaller。现在看来,这根本不是一个嘲弄
public class XmlMarshallerTest {
@Mock
JAXBContext ctx;
@Mock
Marshaller marshaller;
@Mock
JAXBContextFactory factory;
@InjectMocks
XmlMarshaller classUnderTest;
@Before
public void setup() {
MockitoAnnotations.initMocks(this); // creates mocks and injects the as needed into the classUnderTest
when(ctx.createMarshaller()).thenReturn(marshaller);
}
@Test
public void toXmlCallsJAXBMarshaller() {
when(factory.get(SystemPointDto.class)).thenReturn(ctx);
SystemPointDto systemPointDto = new SystemPointDto();
classUnderTest.toXml(systemPointDto);
verify(marshaller).marshal(eq(systemPointDto), any(ByteArrayOutputStream.class));
}
}