Disqus aplikaci se nepodařilo zobrazit. Jste-li administrátor, prosím shlédněte náš návod co dělat při těchto potížích.
Pekny copy-paste, slystel jste nekdy o DRY ?
Unit test pěkný. Ale konkrétně u RČ bych právě z důvodu existence výjimek raději podle specifikace nevalidoval. Maximálně strukturu ("musí být ve tvaru 5-6 číslic / 4 číslice"). Dávám přednost tomu, když systém raději dovolí zadat i bizarní RČ než aby nedovolil zadat reálně existující RČ odporující specifikaci. Hezký by byl pro nevalidní RČ warning, ale ne blokace.
Setkal ses na to vašem systému s nějakou výjimkou z daných pravidel?
Pro kontrolu čísla, které se tváří jako rodné číslo, je to asi užitečné. Ale umím si představit, že když ten test neprojde, tak řešením pravděpodobně nebude oprava chyby validátoru, ale doplnění nějaké výjimky do business logiky, jak psal Wefwefwe.
Osobně je mi na testech tohoto typu nepříjemná jejich rozvláčnost, preferuji raději pomocnou metodu a zápis
@Test public void empty () {t(false,"" );}
@Test public void numberFormatException() {t(false,"x123456789");}
ideálně zformátovaný i do sloupců (code formatting conventions nejsou dogma).
Pak ale nepotřebujete Javu, ale nějaký úspornější jazyk typu Groovy. Váš příklad je velmi nepříjemný v tom, že když spadne, není jasné na jakém místě. Absence zpráv v assertech je jen další hřebíček. Takový test bych po vás luštit nechtěl.
Možná Vašim námitkám nerozumím, ale ani jedna mi nepřijde opodstatněná. Dodávám, jak by vypadala metoda t:
private void t(boolean expected,String input) {
boolean actual = validator.isValid(input);
String msg = String.format("chyba pro %s, ocekavano %s, vysledek %s",input,expected,actual);
assertEquals(msg,expected,actual);
}
- Když test spadne, je místo jasné ze stacktracu. kde je název test metody i řádek. Jen je tam o 1 stackframe víc. Trochu nečitelnější by to bylo při více volání t v rámci jednoho @Testu, obzvlášť kdyby byly na jednom řádku, ale to já také nepovažuji za dobré.
- Absence zpráv v assertech je stejný problém u původního jako u mého kódu.
- K luštění kódu - tady na blogu to není v monospaced fontu, ale v IDE ve spojení s blokovým výběrem je to podle mne zápis, který je velmi efektivní jak pro čtení, tak pro editaci. Metoda t se může jmenovat výstižněji.
Podle mě tady jde jen o dodržení DRY principu, výhody přechodu na typově slabý jazyk mi pro tento případ přijdou přinejmenším diskutabilní.
Groovy bohužel ještě není v Java komunitě tolik rozšířené, tak jsem pro názornost zvolil Javu.
Díky za nápad.
public class RCValidatorTest {
private RCValidator validator;
private boolean expectedIsValid;
private String validatorInput;
private String expectingMessage;
public RCValidatorTest( String validatorInput,boolean expectedIsValid, String expectingMessage) {
this.expectedIsValid = expectedIsValid;
this.validatorInput = validatorInput;
this.expectingMessage = expectingMessage;
}
public RCValidatorTest( String validatorInput,boolean expectedIsValid) {
this.expectedIsValid = expectedIsValid;
this.validatorInput = validatorInput;
}
@Before
public void setUp() {
validator = new RCValidator();
}
@Parameters
public static Collection<object[]> getTestData() {
Collection<object[]> ret = new ArrayList<object[]>();
ret.add(new Object[] { "x123456789", false, "maju byt iba cisla" });
ret.add(new Object[] { "7310285169",true, "ukazkove RC"});
ret.add(new Object[] { "7310285169",true}); //pouzi autgenerovany fail masage
....
return ret;
}
@Test
public void testIsValid() {
boolean actual = validator.isValid(validatorInput);
if (actaul != expectedIsValid) {
String msg = expectingMessage;
if (msg == null)
String.format("ocakaval ze rodne cislo '%s' je %s ",validatorInput,expectedIsValid)
fail(msg);
}
assertFalse(result);
}
}
Je to hrozně dlouhý ;-)
Asi bych ty testovaný hodnoty naládovat do nějaké kolekce nebo mapy a nechal to prosvištět je dvěma testy - dobrý RČ a špatný RČ.
Nebo bych zkusil v Javě najít něco jako tabulková fakta:
https://github.com/marick/M...
Ano, je to dlouhé. Na druhou stranu, když máš test s deseti asserty a první padne, tak ho opravíš, spustíš a třeba druhý padne. Takhle vidíš výsledky všech assertů paralelně.
ne vzdy, ale casto se zadava rodne cislo jako soucast formulare s vice osobnimi udaji. U samotneho validatoru RC to smysl nema, ale jinak jeste lze porovnavat zadanou hodnotu s udajem o pohlavi
V rámci user experience bych neprudil s vyplňováním údajů, které lze odvodil. Proto bych datum narození a pohlaví odvozoval z rodného čísla.
Zajímalo by mě, z jakého důvodu assertujete result a ne rovnou výsledek isValid(String)?
Pak bych také vylepšil názvy testů, když už je máte takhle rozdělené, a nebo alespoň bych v assertu použil message.
Totiž "Selhal oldValid9" - není moc návodné co se vlastně stalo.
Moc never tomu co se pise. Napriklad u naturalizovanych cizincu je pouzito puvodni cislo pasu jako rodne cislo. Jindy urednik na matrice proste udelal chybu. A jsou i lide kteri jsou obcany CR, ale rodne cislo proste nemaji.
Skutečně jste se setkal s nějakým cizincem, který měl místo RČ původní číslo pasu?
Pocital jsem mzdy, tak o tom vim dost. Probiralo se to o Dagiho na blogu asi pet let zpatky.
Díky moc za článek - my takový validátor taky samozřejmě máme a tak jsem si zkusmo doplnil tebou popisované use-casy do našeho testu a voila - prošly všechny. Každopádně dík za nasdílení, protože 2x měř a jednou řež.
Sice se tu strhlo zbytečné lynčování ohledně formy těch testů, ale je lepší mít nějaké testy než testy žádné.
Co se týká validace - vždycky je možné postupovat způsobem, že uživatele pustíme dál i když RČ neodpovídá (aby se pokryly zmíněné vyjímky), ale 99% uživatelů se spíš při psaní uklepne, než že by bylo tolik vyjímek. V takovém případě ho můžeme varovat, že se pravděpodobně zmýlil a jestli se nechce opravit.
Lepší, než vůbec nevalidovat nebo validovat jen číselný formát, jak se tu v komentářích doporučuje.