Skip to content

Instantly share code, notes, and snippets.

@rschumm
Created May 4, 2012 19:48
Show Gist options
  • Save rschumm/2597281 to your computer and use it in GitHub Desktop.
Save rschumm/2597281 to your computer and use it in GitHub Desktop.
FakeRecorder and FakeUnmarshaller für Testdaten.

Kleines Proof-of-Concept zum Recorden und Mocken von Schnittstellen.

Rémy Schumm, 4. 5. 2012

Die Klasse FakeRecorder kann Testdatenpaar von Suchkriterium und Resultat von einem Realen Service aufnehmen und als XML-Files ablegen.

Die Klasse FakeUnmarshaller kann diese XML-Daten aufgrund der Suchkriterien wieder rekonstruieren und über ein FakeBean ausliefern.

Zur Verwendung siehe den UnitTest FakeTest.

Technische Details: Zur Umwandlung von und zu XML wird JAXB verwendet. Zur Identifikation der Suchkriterien wird ein md5-Hash über die toString() Methode des Suchkriteriums gemacht.

Das Root-Element der Resultatklasse muss mit @XmlRootElement annotiert sein. Alle beiteiligten Klassen müssen Serializable sein.

package ch.schumm.fakeservice.bean;
import ch.schumm.fake.FakeUnmarshaller;
import ch.schumm.fakeservice.model.Kunde;
import ch.schumm.fakeservice.model.Suchkriterium;
/**
* Ein Fake-Bean, das den FakeUnmarshaller benutzt.
* @author C709360
*
*/
public class FakeBean implements KundeBean {
public class KundeBeanException extends RuntimeException {
private static final long serialVersionUID = 1L;
public KundeBeanException(Exception e) {
super(e);
}
}
public Kunde getKundeForKriterium(Suchkriterium kriterium) {
try {
FakeUnmarshaller<Suchkriterium, Kunde> fakeUnmarshaller = new FakeUnmarshaller<Suchkriterium, Kunde>();
return fakeUnmarshaller.unmarshallResultForKriterium(kriterium, Kunde.class);
} catch (Exception e) {
throw new KundeBeanException(e);
}
}
}
package ch.schumm.fake;
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.PropertyException;
import org.apache.commons.codec.digest.DigestUtils;
import ch.schumm.fakeservice.bean.RealBean;
import ch.schumm.fakeservice.model.Kunde;
import ch.schumm.fakeservice.model.Suchkriterium;
/**
* Nimmt Fake-Daten von einem realen Service auf und legt sie mittels JAXB als XML-Dateien ab. <br>
* Die Dateinamen der XML-Dateien werden aus dem md5-Hash der Suchkriterien erzeugt. Dazu müssen sie eine eindeutige toString-Methode
* implementieren.
*
* @author C709360 Rémy Schumm
*
* @param <S> Typ des Suchkriteriums
* @param <R> Typ des Resultats.
*/
public class FakeRecorder<S,R> {
/**
* Nimmt einen Testdatensatz auf.
* @param suche das Suchkriterium
* @param result das Resultat des realen Service.
* @throws JAXBException
* @throws PropertyException
*/
public void record(S suche, R result)
throws JAXBException, PropertyException {
JAXBContext context = JAXBContext.newInstance(result.getClass());
// Marshalling...
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
String md5key = generateHashKey(suche);
m.marshal(result, new File(md5key + ".xml"));
}
public static String generateHashKey(Object suche) {
String key = DigestUtils.md5Hex(suche.toString());
return key;
}
}
package ch.schumm.fakeservice.bean;
import static org.junit.Assert.*;
import org.junit.Test;
import ch.schumm.fake.FakeRecorder;
import ch.schumm.fakeservice.model.Kunde;
import ch.schumm.fakeservice.model.Suchkriterium;
/**
* Testet die FakeRecorder und FakeUnmarshaller Infrastruktur.
* @author C709360
*
*/
public class FakeTest {
@Test
public void testRecorder() throws Exception {
RealBean bean = new RealBean();
Suchkriterium hufnagelsuche = RealBean.generateHufnagelSuche();
Kunde hufnagel = bean.getKundeForKriterium(hufnagelsuche);
Suchkriterium schummsuche = RealBean.generateSchummSuche();
Kunde schumm = bean.getKundeForKriterium(schummsuche);
FakeRecorder<Suchkriterium, Kunde> recorder = new FakeRecorder<Suchkriterium, Kunde>();
recorder.record(schummsuche, schumm);
recorder.record(hufnagelsuche, hufnagel);
}
@Test
public void testFakeImplSchumm() {
KundeBean fakebean = new FakeBean();
Kunde kunde = fakebean.getKundeForKriterium(RealBean
.generateSchummSuche());
assertEquals("Josef Schumm wohnt an Schlossgasse in Coburg",
kunde.toString());
}
@Test
public void testFakeImpl() {
KundeBean fakebean = new FakeBean();
Kunde kunde = fakebean.getKundeForKriterium(RealBean
.generateHufnagelSuche());
assertEquals("Barbara Hufnagel wohnt an Hanauer Strasse in Alzenau",
kunde.toString());
}
}
package ch.schumm.fake;
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
/**
* Reproduziert die mit dem FakeRecoder aufgenommen Testdaten.
*
* @author C709360
*
* @param <S> Typ des Suchkriteriums
* @param <R> Typ des Resultats.
*/
public class FakeUnmarshaller<S, R> {
/**
* Rekonstruiert die Testdaten für ein Suchkriterium.
* @param kriterium das Suchkriterium.
* @param rootClassResult Der Klassentyp des Resultats.
* @return
* @throws Exception
*/
public R unmarshallResultForKriterium(S kriterium, Class<R> rootClassResult) throws Exception {
String key = FakeRecorder.generateHashKey(kriterium);
JAXBContext context = JAXBContext.newInstance(rootClassResult);
// Unamarshalling...
Unmarshaller u = context.createUnmarshaller();
@SuppressWarnings("unchecked")
R kunde = (R) u.unmarshal(new File(key + ".xml"));
return kunde;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment