Ложный вызов метода внутреннего объекта с использованием EasyMock - PullRequest
0 голосов
/ 14 июня 2019

У меня есть класс следующим образом

class ClassA {
    public FinalObject classAMethod() {
        ClassB objectB = new ClassB();
        FinalObject objectE = objectB.methodCall();
        return objectE;
    }
}

Теперь с помощью EasyMock я могу сделать

ClassB objectB = EasyMock.createMock(ClassB.class);

EasyMock.expect(objectB.methodCall())).andReturn(new FinalObject()});

Однако для объекта ClassB создается внутри classAMethod(). Как мне посмеяться над этим и заставить его вернуть objectE, который я хочу?

По сути, я пытаюсь протестировать различные сценарии для objectD.methodCall (), например поведение, когда он возвращает исключения, и другой набор значений.

1 Ответ

0 голосов
/ 15 июня 2019

Как уже упоминалось в комментариях, вам нужен PowerMock, чтобы сделать такую ​​вещь. Вот пример.

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.mock;
import static org.junit.Assert.assertSame;
import static org.powermock.api.easymock.PowerMock.expectNew;
import static org.powermock.api.easymock.PowerMock.replay;

class ClassA {
    public FinalObject classAMethod() {
        ClassB objectB = new ClassB();
        FinalObject objectE = objectB.methodCall();
        return objectE;
    }
}

class ClassB {

    public FinalObject methodCall() {
        return null;
    }
}

class FinalObject {}

@RunWith(PowerMockRunner.class)
@PrepareForTest(ClassA.class)
public class MyTest {

    @Test
    public void test() throws Exception {
        ClassB mock = mock(ClassB.class);

        expectNew(ClassB.class).andReturn(mock);

        FinalObject value = new FinalObject();
        expect(mock.methodCall()).andReturn(value);

        replay(mock, ClassB.class);

        ClassA a = new ClassA();
        assertSame(value, a.classAMethod());
    }
}

Однако я стараюсь использовать PowerMock как можно меньше. Создание экземпляра класса, а затем вызов его, часто является запахом кода. Затем, если мне действительно нужно сделать это по какой-то причине, я обычно изолирую создание экземпляра класса от другого метода. Это дает мне тот же результат без темной магии PowerMock.

import org.junit.Test;

import static org.easymock.EasyMock.*;
import static org.junit.Assert.assertSame;

class ClassA {
    public FinalObject classAMethod() {
        ClassB objectB = newB();
        return objectB.methodCall();
    }

    ClassB newB() {
        return new ClassB();
    }
}

class ClassB {

    public FinalObject methodCall() {
        return null;
    }
}

class FinalObject {}

public class MyTest {

    @Test
    public void test() {
        ClassB b = mock(ClassB.class);
        ClassA a = partialMockBuilder(ClassA.class)
                .addMockedMethod("newB")
                .mock();

        FinalObject value = new FinalObject();
        expect(b.methodCall()).andReturn(value);

        expect(a.newB()).andReturn(b);

        replay(a, b);

        assertSame(value, a.classAMethod());
    }
}
...