Štítky

auta (18) běh (34) beskydy (13) brusle (34) cukroví (11) divadlo (1) DIY (2) filmy (17) golf (1) hory (37) IT (68) jednokolka (1) kola (109) kolce (10) koloběžky (4) koncert (4) koně (1) létání (20) lezení (22) literatura (8) lodě (2) lyže (130) motorky (61) osobni (1) osobní (102) plavání (4) posilování (2) potraviny (27) příroda (8) recenze (3) recepty (62) sauna (1) squash (3) tanec (3) telefony (19) turistika (60) USA (58) vlaky (4) vysocina (3) wakeboarding (1) závod (1) závody (84) ZLM (66)

středa 1. října 2014

Java unit testy a změna static final fieldů

Při psaní unit testů se čas od času dostanete do situace, kdy by se hodilo změnit hodnotu static final fieldů. Jeden z nejjednodušších a zároveň nejšpinavějších triků je využití reflexe. Ukážeme si to na příkladu.

Mějme následující třídu, kterou chceme otestovat:
public class Foo {

    public static  String BAR = "bar";

    public Foo() {
    }

    public static int fooMethod(final String fooParameter) {
        try {
            if (!BAR.isEmpty()) {
                return ((BAR + fooParameter).length());
            } else {
                throw new IllegalArgumentException();
            }
        } catch (IllegalArgumentException e) {
            throw new RuntimeException();
        }
    }
}

A příslušný unit test:

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

import org.junit.Test;

public class FooTest {

    @Test(expected = RuntimeException.class)
    public void testFooMethodEmptyStaticFinalField() throws Exception {
        // set public static field BAR to empty string to be able test
        Field staticField = Foo.class.getDeclaredField("BAR");
        staticField.setAccessible(true);
        Field staticFieldModifiers = staticField.getClass().getDeclaredField("modifiers");
        staticFieldModifiers.setAccessible(true);
        staticFieldModifiers.setInt(staticField, staticField.getModifiers() & ~Modifier.FINAL);
        staticField.set(null, "");

        Foo.fooMethod("any vaue");
    }
}

Původní třídu však musíme modifikovat následujícím způsobem:
public class Foo {

    public static  String BAR = new String("bar");

    public Foo() {
    }

    public static int fooMethod(final String fooParameter) {
        try {
            if (!BAR.isEmpty()) {
                return ((BAR + fooParameter).length());
            } else {
                throw new IllegalArgumentException();
            }
        } catch (IllegalArgumentException e) {
            throw new RuntimeException();
        }
    }
}
A voila...

Žádné komentáře:

Okomentovat