I stumbled upon your question while googling for the same thing. If found this post, but didn't like the idea of having to "parse" the generated XML afterwards. After sieving through the JAXB Javadoc, I found an approach the I quite like. A JAXB Marshaller
offers a method that takes a SAX ContentHandler
as an argument. You can mock that ContentHandler
and verify that specific methods have been called with the expected arguments.
Here's a little example. I wrote a custom Attributes
matcher that only verifies presence of certain attribute local names, but does not look at the values (yet). I hope you find this helpful:
@Mock
private ContentHandler handler;
private JAXBContext context;
private ObjectFactory factory;
private Marshaller marshaller;
@Before
public void setUp() throws Exception
{
context = JAXBContext.newInstance(getClass().getPackage().getName());
factory = new ObjectFactory();
marshaller = context.createMarshaller();
}
@Test
public void test() throws Exception
{
final UpdateDescription description = new UpdateDescription("identifier", "version");
final JAXBElement<UpdateDescription> element = factory.createUpdateDescription(description);
marshaller.marshal(element, handler);
verify(handler).startDocument();
verify(handler).startElement(anyString(), eq("description"), anyString(), any(Attributes.class));
verify(handler).startElement(anyString(), eq("identifier"), anyString(), attrs("value"));
verify(handler).startElement(anyString(), eq("version"), anyString(), attrs("value"));
verify(handler).endDocument();
}
private static Attributes attrs(final String... localNames)
{
final Matcher<Attributes> matcher = new TypeSafeMatcher<Attributes>()
{
private Set<String> names = Sets.<String> newHashSet(localNames);
@Override
public void describeTo(final Description description)
{
// TODO Auto-generated method stub
}
@Override
public boolean matchesSafely(final Attributes item)
{
final Set<String> presentLocalNames = Sets.newHashSetWithExpectedSize(item.getLength());
final int length = item.getLength();
for (int i = 0; i < length; ++i) {
presentLocalNames.add(item.getLocalName(i));
}
return Sets.difference(names, presentLocalNames).isEmpty();
}
};
return new ThreadSafeMockingProgress().getArgumentMatcherStorage().reportMatcher(matcher).returnFor(
new AttributesImpl());
}