Подтвердить что ты не робот

Как я имитирую статические методы в классе с помощью easymock?

Предположим, что у меня есть класс:

public class StaticDude{
    public static Object getGroove() {
        // ... some complex logic which returns an object
    };
}

Как мне высмеять вызов статического метода, используя простой макет? StaticDude.getGroove().

Я использую простой mock 3.0

4b9b3361

Ответ 1

Не уверен, как с чистым EasyMock, но подумайте об использовании расширений PowerMock для EasyMock.

У этого есть много классных функций для того, чтобы делать только то, что вам нужно - https://github.com/jayway/powermock/wiki/MockStatic

Ответ 2

Easymock - это платформа тестирования для "для интерфейсов (и объектов через расширение класса)", чтобы вы могли издеваться над классом без интерфейса. Подумайте о создании сопряженного объекта с помощью аксессуар для вашего статического класса, а затем издевайтесь над этим ассемблером.

EDIT: Btw, я бы не рекомендовал делать статические классы. Лучше иметь все сопряженное, если вы делаете TDD.

Ответ 3

Только в случае PowerMock недоступен по любой причине:

Вы можете перенести статический вызов на метод, переопределить этот метод при создании тестируемого класса в тестовом классе, создать локальный интерфейс в тестовом классе и использовать его метод в методе overside:

private interface IMocker 
{
    boolean doSomething();
}

IMocker imocker = EasyMock.createMock(IMocker.class);

...

@Override
void doSomething()
{
     imocker.doSomething();
}

...

EasyMock.expect(imocker.doSomething()).andReturn(true);

Ответ 4

Вообще говоря, не представляется возможным издеваться над статическим методом, не используя какой-то аксессор, который, похоже, преследует цель использования статического метода. Это может быть довольно неприятно.

Есть один инструмент, который я знаю о названии "TypeMock Isolator", который использует какую-то сатанинскую магию, чтобы издеваться над статическими методами, но этот инструмент довольно дорог.

Проблема в том, что я не знаю, как переопределить статический метод. Вы не можете объявить его виртуальным. вы не можете включить его в интерфейс.

Извините, что отрицательный nelly.

Ответ 5

Добавление примера о том, как реализовать статический макет по регулярному макету вводимых классов с помощью EasyMock/PowerMock, поскольку связанный пример показывает только статический макет.

И с помощью PowerMockRunner службы @Mock не подключены к службе @TestSubject для тестирования.

Скажем, у нас есть сервис, который мы хотим проверить, ServiceOne:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class ServiceOne {

    @Autowired
    private ServiceTwo serviceTwo;

    public String methodToTest() {
        String returnServ2 = serviceTwo.methodToMock();
        return ServiceUtils.addPlus(returnServ2);
    }
}

Что вызывает другую услугу, которую мы хотим высмеять, ServiceTwo:

import org.springframework.stereotype.Service;

@Service
public class ServiceTwo {

    public String methodToMock() {
        return "ServiceTwoReturn";
    }
}

И который вызывает статический метод конечного класса, ServiceUtils:

public final class ServiceUtils {

    public static String addPlus(String pParam) {
        return "+" + pParam;
    }
}

При вызове ServiceOne.methodToTest() мы получаем "+ServiceTwoReturn" как возврат.


Junit Test с EasyMock, высмеивая только внедренную службу ServiceTwo Spring:

import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.junit.Assert.assertEquals;

import org.easymock.EasyMockRunner;
import org.easymock.Mock;
import org.easymock.TestSubject;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(EasyMockRunner.class)
public class ExempleTest {

    @TestSubject
    private ServiceOne serviceToTest = new ServiceOne();

    @Mock
    private ServiceTwo serviceMocked;

    @Test
    public void testMethodToTest() {
        String mockedReturn = "return2";

        expect(serviceMocked.methodToMock()).andReturn(mockedReturn);
        replay(serviceMocked);

        String result = serviceToTest.methodToTest();

        verify(serviceMocked);

        assertEquals("+" + mockedReturn, result);
    }
}

Junit Test с EasyMock и PowerMock, высмеивая внедренную службу ServiceTwo Spring, а также последний класс и его статический метод:

import static org.easymock.EasyMock.expect;
import static org.junit.Assert.assertEquals;
import static org.powermock.api.easymock.PowerMock.createMock;
import static org.powermock.api.easymock.PowerMock.mockStatic;
import static org.powermock.reflect.Whitebox.setInternalState;

import org.easymock.Mock;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(ServiceUtils.class)
public class ExempleTest {

    private ServiceOne serviceToTest;

    private ServiceTwo serviceMocked;

    @Before
    public void setUp() {
        serviceToTest = new ServiceOne();
        serviceMocked = createMock(ServiceTwo.class);
        // This will wire the serviced mocked into the service to test
        setInternalState(serviceToTest, serviceMocked);
        mockStatic(ServiceUtils.class);
    }

    @Test
    public void testMethodToTest() {
        String mockedReturn = "return2";
        String mockedStaticReturn = "returnStatic";

        expect(serviceMocked.methodToMock()).andReturn(mockedReturn);
        expect(ServiceUtils.addPlus(mockedReturn)).andReturn(mockedStaticReturn);
        PowerMock.replayAll();

        String result = serviceToTest.methodToTest();

        PowerMock.verifyAll();

        assertEquals(mockedStaticReturn, result);
    }
}