Frage Testcode, der native Methoden aufruft


Ich habe eine Klasse wie diese:

public final class Foo
{
    public native int getBar();

    public String toString()
    {
        return "Bar: " + getBar();
    }
}

Bitte beachte, dass getBar () ist mit JNI implementiert und die Klasse ist Finale. Ich möchte einen Junit Test schreiben um das zu testen toString () Methode. Dafür muss ich das verspotten getBar () Methode und dann das Original ausführen toString () Methode, um die Ausgabe zu überprüfen.

Mein erster Gedanke war, dass dies unmöglich sein muss, aber dann habe ich gefunden PowerMock unterstützt das Testen finaler Klassen und nativer Methoden gemäß der Feature-Liste. Aber bis jetzt hatte ich keinen Erfolg damit. Die beste Sache, die ich schaffte, war, die komplette Klasse zu verspotten, aber dann testete der Test das Gespottete toString () Methode anstelle der realen, die nicht viel Sinn macht.

Wie kann ich PowerMock verwenden, um dies zu testen? toString () Methode von oben? Ich bevorzuge PowerMock mit Mockito Aber wenn das nicht möglich ist, habe ich kein Problem damit EasyMock stattdessen.


10
2018-02-06 21:21


Ursprung


Antworten:


Fand es. Die Art, wie ich es gemacht habe, war richtig. Das einzige, was ich vermisste, war, dass das Mock-Objekt die ursprüngliche Methode aufruft, wenn toString aufgerufen wurde (). So funktioniert es so:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ Foo.class })
public class FooTest
{
    @Test
    public void testToString() throws Exception
    {
        Foo foo = mock(Foo.class);
        when(foo.getBar()).thenReturn(42);
        when(foo.toString()).thenCallRealMethod();
        assertEquals("Bar: 42", foo.toString());
    }
}

8
2018-02-06 22:04



Oder benutzen JMockit mit dynamisches partielles Mocking:

import org.junit.*;
import mockit.*;

public class FooTest
{
    @Test
    public void testToString()
    {
        final Foo foo = new Foo();
        new Expectations(foo) {{ foo.getBar(); result = 42; }};

        assertEquals("Bar: 42", foo.toString());
    }
}

3
2018-02-11 15:16



Oder benutzen Strategie-Muster:

    public final class Foo
    {
        public IBarStrategy barStrategy;

        ......
    }

    interface IBarStrategy{
        int getBar();
    }

Beim Komponententest einen Schein einspritzen IBarStrategy Beispiel, dann könnten Sie die Klasse testen Foo.


1
2018-02-07 04:31