Article Image
Article Image
read

Continuando com o código do post anterior …

Agora é criar uma classe de testes separada para os testes de serialização. Desta vez usei o MockSerializationResult que é o mock que o VRaptor 3.4 disponibiliza e como eu disse no post anterior não existia no SNAPSHOT 3.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
public class SerializeEventoControllerTest {
	private MockSerializationResult result;
	private EventoController controller;
	@Mock
	private EventoDAO eventoDAO;

	@Before
	public void setup(){
		MockitoAnnotations.initMocks(this);
		this.result = new MockSerializationResult();
		this.controller = new EventoController(this.result, this.eventoDAO);
	}
}

Agora é hora de criar os métodos de teste, eles são bem parecidos com os anteriores a diferença é como pegamos o objeto serializado, precisamos chamar o método serializedResult do MockSerializationResult.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Test
public void deveRetornarUmEventoNoFormatoJSON() throws Exception {
	Evento evento = Dado.umEvento(1L, "BACONSP", "Bacon Conference SP", "Av Paulista", 
		Calendar.getInstance());
	Mockito.when(this.eventoDAO.load(evento.getId())).thenReturn(evento);

	this.controller.showJSON(1L);

	String esperado = Entao.deveRetornaJSONde(evento);
	String retornado = this.result.serializedResult();

	Assert.assertThat(retornado, is(equalTo(esperado)));
}

@Test
public void deveRetornarUmaListaDeEventoNoFormatoJSON() throws Exception {
	List<Evento> eventos = Dado.umaListaCadastrada();
	Mockito.when(this.eventoDAO.list()).thenReturn(eventos);

	this.controller.listJSON();

	String esperado = Entao.deveRetornaListaJSONde(eventos);
	String retornado = this.result.serializedResult();

	Assert.assertThat(retornado , is(equalTo(esperado)));
}

Também criei novos métodos na classe Entao para me ajudar nos assert’s. Para não ter que ficar criando o JSON na mão usei o XStream, a mesma coisa que o VRaptor internamente usa.

1
2
3
4
5
6
7
8
9
10
11
12
13
public static String deveRetornaJSONde(Evento evento) {
	XStream xstream = getXStreamJSON();

	xstream.alias("evento", Evento.class);
	return xstream.toXML(evento);
}

public static String deveRetornaListaJSONde(List<Evento> eventos) {
	XStream xstream = getXStreamJSON();

	xstream.alias("eventos", List.class);
	return xstream.toXML(eventos);
}

Poréms se você usar o XStream diretamente com o Jettison, seus testes não vão passar, pois o VRaptor utiliza uma indentação diferente do padrão do XStream para o JSON. Por isso o método getStreamJSON() na classe Entao. Esse código peguei da classe do VRaptor XStreamJSONSerialization. Dá pra melhorar pra classe de teste mas vou deixar assim mesmo, eu só não sei por que eles colocaram esse espaço internamente no framework.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
private static final String DEFAULT_NEW_LINE = "";
private static final char[] DEFAULT_LINE_INDENTER = {};
private static final String INDENTED_NEW_LINE = "\n";
private static final char[] INDENTED_LINE_INDENTER = { ' ', ' ' };
private static boolean withoutRoot = false;
private static boolean indented = false;

private static XStream getXStreamJSON() {
	final String newLine = (indented ? INDENTED_NEW_LINE : DEFAULT_NEW_LINE);
	final char[] lineIndenter = (indented ? 
		INDENTED_LINE_INDENTER : DEFAULT_LINE_INDENTER);

	XStream xstream = new XStream(new JsonHierarchicalStreamDriver(){
		public HierarchicalStreamWriter createWriter(Writer writer) {
			if (withoutRoot) {
				return new JsonWriter(writer, lineIndenter, newLine, 
					JsonWriter.DROP_ROOT_MODE);
			}
			return new JsonWriter(writer, lineIndenter, newLine);
		}
	});
	return xstream;
}

Agora vamos criar os testes para o XML na classe SerializeEventoControllerTest que são praticamente a mesma coisa:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Test
public void deveRetornarUmEventoNoFormatoXML() throws Exception {
	Evento evento = Dado.umEvento(1L, "BACONSP", "Bacon Conference SP", "Av Paulista", 
		Calendar.getInstance());
	Mockito.when(this.eventoDAO.load(evento.getId())).thenReturn(evento);

	this.controller.showXML(1L);

	String esperado = Entao.deveRetornaXMLde(evento);
	String retornado = this.result.serializedResult();

	Assert.assertThat(retornado, is(equalTo(esperado)));
}

@Test
public void deveRetornarUmaListaDeEventoNoFormatoXML() throws Exception {
	List<Evento> eventos = Dado.umaListaCadastrada();
	Mockito.when(this.eventoDAO.list()).thenReturn(eventos);

	this.controller.listXML();

	String esperado = Entao.deveRetornaListaXMLde(eventos);
	String retornado = this.result.serializedResult();

	Assert.assertThat(retornado , is(equalTo(esperado)));
}

E também os métodos de assert que pra XML são mais simples:

1
2
3
4
5
6
public static String deveRetornaXMLde(Evento evento) {
	XStream xstream = new XStream();

	xstream.alias("evento", Evento.class);
	return xstream.toXML(evento);
}

Um detalhe é que para uma lista, temos que indicar ao XStream para serializar a lista e os objetos que ela contém:

1
2
3
4
5
6
7
public static String deveRetornaListaXMLde(List<Evento> eventos) {
	XStream xstream = new XStream();

	xstream.alias("eventos", List.class);
	xstream.alias("evento", Evento.class);
	return xstream.toXML(eventos);
}

Finalmente vamos criar os métodos no EventoController que transformar os eventos e listas de eventos em XML e/ou JSON. Para isso precisamos indicar para o Result qual o formato que ele deve disponibilizar para a view, inserir o objeto e “mandar” serializar. Essa seria a forma programática, para outras formas tente isso.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void showXML(Long id) {
	this.result.use(Results.xml()).from(this.eventoDAO.load(id), "evento").serialize();
}

public void showJSON(Long id) {
	this.result.use(Results.json()).from(this.eventoDAO.load(id), "evento").serialize();
}

public void listXML() {
	this.result.use(Results.xml()).from(this.eventoDAO.list(), "eventos").serialize();
}

public void listJSON() {
	this.result.use(Results.json()).from(this.eventoDAO.list(), "eventos").serialize();
}

Era isso que queria compartilhar, simples não? :)

O código está AQUI.

Inté manolos…

Blog Logo

Marcelo Tozzi


Published

Image

Marcelo Tozzi

Mais um blog de desenvolvedor

Back to Overview