Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

PowerMock( Mockito) TestNG и мокинг статических классов/методов

Anna | 5.06.2014 | нет комментариев

На прогре теснее была статья с примерами применения PowerMock, но в ней не хватает такого изложения, как мокирование статических способов как независимых «единиц» в классе, так и в гибридном применении, когда часть статических способов у класса мокируются, а часть вызываются реально. Испробую поправить эту нишу.

Для начала сотворим демонстрационный класс со статическими способами (коммит):

public class ClassStatic {
	static String getValue() {
		return "value";
	}

	static String getValue(final String s) {
		return getValue()   s;
	}
}


Добавим примитивное тестирование неподвижных способов. Для этого сотворим класс ClassStaticTest (коммит):

import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

@Test(groups = {"static", "noMock"})
public class ClassStaticTest {
	@DataProvider
	public Object[][] data() throws Exception {
		return new Object[][]{{"", "value"}, {"test", "valuetest"}};
	}

	@Test
	public void testGetValueVoid() throws Exception {
		Assert.assertEquals(ClassStatic.getValue(), "value");
	}

	@Test(dataProvider = "data", dependsOnMethods = {"testGetValueVoid"})
	public void testGetValueAttribute(final String v, final String r) throws Exception {
		Assert.assertEquals(ClassStatic.getValue(v), r);
	}
}

До этого момента мы ни разу не применяли PowerMock, так как он нам не требовался. Сейчас же, Дабы сделать мокирование для способов, сотворим «костяк»:

import org.powermock.modules.testng.PowerMockObjectFactory;
import org.testng.IObjectFactory;
import org.testng.annotations.ObjectFactory;
import org.testng.annotations.Test;

@Test(groups = {"static", "mock"})
public class ClassStaticMockTest {
	@ObjectFactory
	public IObjectFactory setObjectFactory() {
		return new PowerMockObjectFactory();
	}
}

Мы сотворили класс ClassStaticMockTest, в котором переопределили Object Factory для TestNG (документация)

Добавим тест с мокированием статического способа:

import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockObjectFactory;
import org.testng.Assert;
import org.testng.IObjectFactory;
import org.testng.annotations.DataProvider;
import org.testng.annotations.ObjectFactory;
import org.testng.annotations.Test;

import static org.mockito.MockitoAnnotations.Mock;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.when;

@Test(groups = {"static", "mock"})
@PrepareForTest({ClassStatic.class})
public class ClassStaticMockTest {

	@Mock
	public ClassStatic classStatic;

	@DataProvider
	public Object[][] data() throws Exception {
		return new Object[][]{{"", "newValue"}, {"test", "newValuetest"}};
	}

	@ObjectFactory
	public IObjectFactory setObjectFactory() {
		return new PowerMockObjectFactory();
	}

	@Test(dependsOnGroups = {"noMock"})
	public void mockGetValueVoid() throws Exception {
		mockStatic(ClassStatic.class);
		when(ClassStatic.getValue()).thenReturn("newValue");
		Assert.assertEquals(ClassStatic.getValue(), "newValue");
	}
}

Остался заключительный "аккорд" - гибридный тест, в котором один статический способ замокирован, а для иного делается настоящий вызов (суммарный <a href="https://github.com/BorzdeG/ru.itbasis.demo.mock.staticMethod/tree/3ae2fea05c70ae8b644010cd9f48bd05951ceaba">коммит</a>): 
<source lang="java">
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockObjectFactory;
import org.testng.Assert;
import org.testng.IObjectFactory;
import org.testng.annotations.DataProvider;
import org.testng.annotations.ObjectFactory;
import org.testng.annotations.Test;

import static org.mockito.MockitoAnnotations.Mock;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.when;

/** Created by borz on 06.07.13. */
@Test(groups = {"static", "mock"})
@PrepareForTest({ClassStatic.class})
public class ClassStaticMockTest {

	@Mock
	public ClassStatic classStatic;

	@DataProvider
	public Object[][] data() throws Exception {
		return new Object[][]{{"", "newValue"}, {"test", "newValuetest"}};
	}

	@ObjectFactory
	public IObjectFactory setObjectFactory() {
		return new PowerMockObjectFactory();
	}

	@Test(dependsOnGroups = {"noMock"})
	public void mockGetValueVoid() throws Exception {
		mockStatic(ClassStatic.class);
		when(ClassStatic.getValue()).thenReturn("newValue");
		Assert.assertEquals(ClassStatic.getValue(), "newValue");
	}

	@Test(dataProvider = "data", dependsOnMethods = {"mockGetValueVoid"})
	public void testGetValueAttribute(final String v, final String r) throws Exception {
		mockStatic(ClassStatic.class);
		when(ClassStatic.getValue()).thenReturn("newValue");
		when(ClassStatic.getValue(v)).thenCallRealMethod();
		Assert.assertEquals(ClassStatic.getValue(v), r);
	}
}

Мы перекрываем вызов способа getValue() и указываем, что при вызове getValue(String value) будет вызван настоящий способ у класса, тот, что теснее внутри себя вызывает getValue().

Как пример применения мокирования статических способов является «перекрытие» вызовов способов одного класса в ином (коммит).

Добавляем класс, использующий у себя статический способ ClassStatic.getValue():

public class ClassUseStatic {
	public String getValue() {
		return ClassStatic.getValue()   "noStatic";
	}
}

И добавляем тест для способа ClassUseStatic.getValue() с переопределением вызоваClassStatic.getValue():

import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockObjectFactory;
import org.testng.Assert;
import org.testng.IObjectFactory;
import org.testng.annotations.DataProvider;
import org.testng.annotations.ObjectFactory;
import org.testng.annotations.Test;

import static org.mockito.MockitoAnnotations.Mock;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.when;

@Test(groups = {"useStatic", "mock"}, dependsOnGroups = {"static"})
@PrepareForTest({ClassStatic.class})
public class ClassUseStaticTest {
	@Mock
	public ClassStatic classStatic;

	@DataProvider
	public Object[][] data() throws Exception {
		return new Object[][]{{"newValue1", "newValue1noStatic"}, {"newValue2", "newValue2noStatic"}};
	}

	@ObjectFactory
	public IObjectFactory setObjectFactory() {
		return new PowerMockObjectFactory();
	}

	@Test(dataProvider = "data")
	public void testGetValue(String value, String result) throws Exception {
		mockStatic(ClassStatic.class);
		when(ClassStatic.getValue()).thenReturn(value);

		ClassUseStatic testClass = new ClassUseStatic();
		Assert.assertEquals(result, testClass.getValue());
	}
}

PS: Все примеры дозволено обнаружить на GitHub

UPD: добавил пример мокирования статических способов при тестировании «обыкновенных» классов

Источник: programmingmaster.ru

Оставить комментарий
БАЗА ЗНАНИЙ
СЛУЧАЙНАЯ СТАТЬЯ
СЛУЧАЙНЫЙ БЛОГ
СЛУЧАЙНЫЙ МОД
СЛУЧАЙНЫЙ СКИН
НОВЫЕ МОДЫ
НОВЫЕ СКИНЫ
НАКОПЛЕННЫЙ ОПЫТ
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB