Junit4: Aprimoramento: suporte BigDecimal para assertEquals ()

Criado em 25 mar. 2010  ·  27Comentários  ·  Fonte: junit-team/junit4

Usar JUnit para testar valores BigDecimal é sempre um ponto sensível. É porque BigDecimal considera a precisão usando equals (), mas a ignora em compareTo (). A melhor maneira de lidar com isso seria um novo método assertEquals que permite que a precisão seja avaliada opcionalmente. Você também pode adicionar um método alternativo que aceite uma mensagem:

public static void assertEquals (BigDecimal esperado, BigDecimal real, boolean precisionMatters) {
if (precisionMatters) {
Assert.assertEquals (esperado, real);
} outro {
Assert.assertEquals (0, expected.compareTo (real));
}
}

feature

Comentários muito úteis

Você já tentou usar comparesEqualTo ?

Todos 27 comentários

Seria uma coisa fácil de montar como um garfo ou remendo; Eu estaria disposto a fazer isso, se apropriado.

Prefiro ter uma asserção assertNumericallyEqualTo do que um sinalizador booleano passado para assertEquals.

É um bom nome. Eu o encurtaria para assertNumericallyEquals ().

Embora eu concorde com o sentimento, não tenho certeza se ter outro método de afirmação com um nome diferente realmente ajudará a esclarecer a confusão, especialmente entre pessoas que estão totalmente inconscientes da diferença ou não encontraram o problema por si mesmas. Quer dizer, se eu não tivesse lido esta edição, teria ido em frente e usado assertEquals() por BigDecimal . No caso geral, funcionaria, de fato, conforme anunciado - funcionaria exatamente como BigDecimal#equals() funciona. Eu até argumentaria que isso é uma coisa boa - força alguém a perceber que BigDecimal#equals() compara valor e escala, então talvez não seja isso que eles estavam tentando realizar - embora, em outros casos, eu afirme que _é_. Quer dizer, em alguns casos, queremos verificar se o valor real retornado por um método é _exatamente_ 'igual' ao valor esperado (não apenas logicamente / numericamente igual). Colocando de outra forma: o que assertNumericallyEquals() fornece (além da brevidade) que assertEquals(0, actual.compareTo(expected)) não oferece? Pessoalmente, eu provavelmente criaria um matcher Hamcrest e usaria assertThat(actual, isNumericallyEqualTo(expected)) se precisasse com frequência - além disso, pode ser usado em qualquer lugar que matcher Hamcrest possa ser usado (validação de dados, entre outros).

Desculpe pelo atraso na pesagem, mas minha opinião pessoal está próxima da de Alistair.

Colocando de outra forma: o que assertNumericallyEquals() fornece (além da brevidade) que assertEquals(0, actual.compareTo(expected)) não oferece?

Comunica a intenção com mais clareza? A abordagem de combinação mais difícil está bem para mim.

Geoffrey,

Você está dizendo que está bem escrevendo esse matcher para seu próprio projeto ou que deseja que ele seja enviado com o hamcrest? Ou JUnit, mas não hamcrest?

Qualquer uma ou todas as opções acima - a maioria dos projetos que escrevo acaba tendo alguns matchers personalizados do hamcrest. Ter casos comuns cobertos por Hamcrest e / ou JUnit economiza um pouco de tempo, mas este também não tem sido um caso muito comum para mim.

Um pequeno ponto sobre mensagens de erro menos úteis. Acabei de converter minhas chamadas Assert.assertEquals para Assert.assertTrue, tendo falhas de acerto na comparação de BigDecimals com Assert.assertEquals. É claro que agora meus testes falham com um tipo de erro "teste booleano falhou", sem me dizer quais eram os valores. Da mesma forma, assertEquals (0, real.compareTo (esperado)) registraria, por exemplo, "esperado 0, mas obtido: 1" quando uma mensagem de erro muito mais útil seria de assertNumericallyEquals (real, esperado) seria "esperado 12,45, mas obtido : 123 "(os valores reais dos argumentos 'reais' e 'esperados').

http://www.bssd.eu/blog/?p=113 também torna uma leitura interessante.

assertEquivalent de https://github.com/KentBeck/junit/pull/228 deve resolver isso.

Obrigado dsaff. Esse trabalho parece ótimo. Eu não fiz isso antes. Isso significa que preciso buscar o código-fonte junit, mesclar essa solicitação de pull sozinho e fazer uma compilação personalizada?

Com a ajuda em http://help.github.com/send-pull-requests/ , parece que eu deveria:

git clone https://github.com/KentBeck/junit.git
cd junit

e, em seguida, adicione um controle remoto para a solicitação pull e, em seguida, busque, mescle ou faça ambos.

Dado que esta parece ser uma solicitação pull, ou seja, junit não oficial, é aconselhável usar em um aplicativo? Alguma chance de isso mofo fora do junit principal e eu terei problemas para enviar meu código para outras pessoas, para quem ele não será compilado?

Neekfenwick,

Sim, você está no caminho certo sobre como fazer isso agora. Pretendo mesclar esse pull no branch 4.10, mas o autor original está tendo problemas para obter o status do git mesclável. Se você tiver tempo para fazer um favor ao mundo, pode bifurcar o repositório KentBeck, mesclar tudo e emitir uma solicitação de pull para o branch 4.10, de modo que seja mais fácil para todos (se estiver parecendo popular, eu poderia até girar em algum momento um jar de visualização 4.10).

Eu realmente nunca fiz isso antes :) Então eu fiz um bifurcação do repo e clonado [email protected] : neekfenwick / junit.git para minha máquina local (eu já tenho uma conta github e chaves ssh configuradas) e adicionei um controle remoto para o repo do qual fiz o bifurcação:

git remote add upstream https://github.com/KentBeck/junit.git

Apenas como medida de segurança, fiz uma ramificação para poder mesclar a solicitação pull em outro lugar que não seja HEAD:

git branch merge_pullreq_228
git checkout merge_pullreq_228

Agora, os documentos que posso encontrar dizem "agora mescle a solicitação pull em seu branch". Posso ver os commits para pull 228 em https://github.com/KentBeck/junit/pull/228/commits, mas não consigo mesclá-los:

[neek junit (merge_pullreq_228)]$ git merge 57b49344
fatal: '57b49344' does not point to a commit

Como a solicitação de pull não é para meu próprio repo / branch, não posso usar as ferramentas Merge no github web gui (AFAIK).

Estou correto em pensar que você quer que eu mescle os 7 commits em meu próprio branch e faça com que ele construa / passe nos testes de unidade? Você poderia explicar o que fazer para mesclar um desses commits e me colocar no caminho certo?

Certo, você não pode usar as ferramentas de mesclagem da web. O que eu acredito que deve funcionar é:

git remote add leet3lite https://github.com/leet3lite/junit.git

E então de sua filial, ligue

git pull leet3lite master

Infelizmente, geralmente esqueço uma coisa ao descrever como usar o git "por telefone", então me diga se isso funciona para você.

Ah, entendo, não preciso mesclar cada um desses commits ... o branch master do leet3lite já os tem, e é o ato de mesclar esse trabalho no master original que é o problema.

Parece haver conflitos de mesclagem entre esse branch e o HEAD. Acho que esse é o objetivo deste exercício.

[neek junit (merge_pullreq_228)]$ git remote add leet3lite https://github.com/leet3lite/junit.git
[neek junit (merge_pullreq_228)]$ git pull leet3lite master
remote: Counting objects: 100, done.
remote: Compressing objects: 100% (39/39), done.
remote: Total 85 (delta 34), reused 77 (delta 26)
Unpacking objects: 100% (85/85), done.
From https://github.com/leet3lite/junit
 * branch            master     -> FETCH_HEAD
Auto-merging acknowledgements.txt
CONFLICT (content): Merge conflict in acknowledgements.txt
Auto-merging src/main/java/org/junit/Assert.java
Auto-merging src/test/java/org/junit/tests/AllTests.java
CONFLICT (content): Merge conflict in src/test/java/org/junit/tests/AllTests.java
Automatic merge failed; fix conflicts and then commit the result.
[neek junit (merge_pullreq_228|MERGING)]$ 

Se isso parecer sensato para você, vou continuar com isso amanhã. Quase meia-noite aqui.

Parece que você está no lugar certo. reconhecgements.txt e AllTests.java são muito tocados, geralmente apenas com adições, portanto, a operação de mesclagem é provavelmente um simples ato de incluir todas as linhas adicionadas em ambos os caminhos.

Muito obrigado por levar isso adiante.

Acho que isso foi consertado há 2 anos.

dsaff --Não ...?

Não no 4.11; (eu também preciso desse recurso

A discussão sobre assertEquivalent() mudou para # 228 e depois disso, acho que mudou para # 376, onde decidimos que realmente Hamcrest deveria resolver isso.

@ junit-team / junit-committers alguma objeção ao meu fechamento?

Sem objeções do meu lado.

Opa, clique freudiano. :-) Sem objeções aqui.

OK. Fechando então.

Não acho que usar o matcher do hamcrest resolva esse problema. Por exemplo, este código:

   assertThat(product.getRating(), is(equalTo(new BigDecimal("2.3"))));

irá produzir este resultado:

Expected: is <2.3>
     but: was <2.30000>

Acho que junit ou hamcrest ainda precisa do método isNumericEquivalent .

Você já tentou usar comparesEqualTo ?

Sim, comparesEqualTo realmente funciona. Obrigado.

Aqui está uma folha de dicas que criei há algum tempo:
http://www.marcphilipp.de/blog/2013/01/02/hamcrest-quick-reference/

Esta página foi útil?
0 / 5 - 0 avaliações