我想模拟以下方法对Xml进行JUnit测试:
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
答案 0 :(得分:0)
在您的方法中,您从Marshaller
获得JAXBContext
。要使用模拟Marshaller,您需要一个JAXBContext,在调用createMarshaller
时返回模拟。
假设下列课程正在测试中:
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
}
}
您的测试设置需要如下所示:
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));
}
}