JUnit - Como eu testaria este Metodo?

Ola galera.
Tenho algumas duvidas quanto a aplicação de testes unitários com JUnit.
uma delas seria como eu testaria o metodo a seguir.:

O objetivo deste método é redimencionar uma imagem passado como InputStream e devolver uma nova como InputStream também.

	public static InputStream redimencionarJPG(InputStream inputStream,
			int largura, int altura) throws Exception {

		byte[] array = new byte[inputStream.available()];
		inputStream.read(array);
		Image image = new ImageIcon( array ).getImage();
		int quality = 100;
		
		
		// Calculos necessários para manter as propoçoes da imagem, conhecido
		// como "aspect ratio"
		double thumbRatio = (double) largura / (double) altura;
		int imageWidth = image.getWidth(null);
		int imageHeight = image.getHeight(null);

		double imageRatio = (double) imageWidth / (double) imageHeight;

		if (thumbRatio < imageRatio) {
			altura = (int) (largura / imageRatio);
		} else {
			largura = (int) (altura * imageRatio);
		}
		// Fim do cálculo

		BufferedImage thumbImage = new BufferedImage(largura, altura,
				BufferedImage.TYPE_INT_RGB);

		Graphics2D graphics2D = thumbImage.createGraphics();

		graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
				RenderingHints.VALUE_INTERPOLATION_BILINEAR);

		graphics2D.drawImage(image, 0, 0, largura, altura, null);

		ByteArrayOutputStream out = new ByteArrayOutputStream();

		try {
			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
			JPEGEncodeParam param = encoder
					.getDefaultJPEGEncodeParam(thumbImage);
			quality = Math.max(0, Math.min(quality, 100));
			param.setQuality((float) quality / 100.0f, false);
			encoder.setJPEGEncodeParam(param);
			encoder.encode(thumbImage);
			return new ByteArrayInputStream( out.toByteArray() );

		} catch (FileNotFoundException e) {
			System.out.println("FileNotFoundException " + e.getMessage());
			throw e;
		} catch (ImageFormatException e) {
			System.out.println("ImageFormatException " + e.getMessage());
			throw e;
		} catch (IOException e) {
			System.out.println("IOException " + e.getMessage());
			throw e;
		}
	}

Obrigado pela atenção.
Abraços.

PQ nao usa objetos Image aos inves de passar e receber streams?

Uma boa pratica é nao modificar a imagem passada como parametro mas sim retornar uma nova imagem com as dimensoes especificadas.

Cara, você até pode até usar Mocks para eliminar algumas dependências do seu método e escrever testes de unidade, mas como a saída do seu método está muito acoplada a estas dependências, eu me focaria mais em testar o seu método como um todo (integração).

Minha sugestão: crie 2 arquivos de imagem, um para ser usado como entrada do seu método e outro para representar a saída esperada. Ou seja, um arquivo é a imagem original e o outro é a imagem já redimensionada (use algum outro programa para gerar o segundo).

Faça um teste que crie um InputStream a partir do seu primeiro arquivo, passe este para o seu método e leia o InputStream que ele retorna. Compare o conteúdo deste stream com o conteúdo do seu segundo arquivo. Eles devem ser idênticos.

Repita o processo com diferentes pares de imagens para verificar como seu algoritmo lida com diferentes alturas/larguras/formatos.

Existem varias formas de redimensionar uma imagem. Provavelmente diferentes algoritmos retornarao diferentes imagens na sua representacao em bytes.

Como eu disse, use imagens e nao streams.

Image retorno = redimensiona(original, largura, altura);

assertEquals(retorno.getWidth(), largura);
assertEquals(retorno.getHeight(), altura);

Concordo que usar Image pode facilitar os testes.

Já no que que se refere a diferentes algoritmos gerarem diferentes imagens, essa pode ser mais uma razão para checar o conteúdo após o redimensionamento, afinal, o resultado não pode ser uma imagem qualquer apenas com as dimensões corretas.

[quote=AnThraX.Java]Ola galera.
Tenho algumas duvidas quanto a aplicação de testes unitários com JUnit.
uma delas seria como eu testaria o metodo a seguir.:

O objetivo deste método é redimencionar uma imagem passado como InputStream e devolver uma nova como InputStream também.
[/quote]

Crie uma imagem usando BufferedImage ou use um JPEG de teste com dimenções conhecidas. Utilize ImageIO para ler a imagem com um InputStream do arquivo e passe-a ao método. Utilize o mesmo ImageIO para ler a imagem do inputStream que retorna do método. Carrege em um Image e teste se as dimenções são as que deveriam ser.

Obrigado.
Entendi a idéia.

Alem de checar se a altura e largura estão de acordo com o esperado, veja se é possivel checar alguma coisa com respeito a informação que a imagem carrega pois vc pode redimensionar mas arrebentar com a imagem.

Uma coisa que seria interessante é ver se o arquivo não corrompeu verificando mais informações. Se vc sempre faz o teste com uma imagem, verifique a qualidade da mesma se for redimensionada e, caso positivo, guarde MD5SUM dela. Em testes subsequentes podes testar esse hash (é provavel que seja sempre o mesmo se os parâmetros do teste permaneçam os mesmos, certo?) ou verifica alguma relação de ruído entre as imagens, etc. Tem muita coisa que pode ser feita ai :slight_smile:

Alem de tudo que foi dito, essa parte de calculo não poderia se transformar em um novo metodo tipo calcularAspectRatio gerando testes especificos?

:stuck_out_tongue: