Prueba JAVA JUnit

Use powermock para escribir java UT.

archivo pom introduce dependencias relacionadas

<!-- PowerMock JUnit 4.4+ Module -->
<dependency>
  <groupId>org.powermock</groupId>
  <artifactId>powermock-module-junit4</artifactId>
  <version>2.0.0</version>
  <scope>test</scope>
</dependency>
<!-- PowerMock Mockito2 API -->
<dependency>
  <groupId>org.powermock</groupId>
  <artifactId>powermock-api-mockito2</artifactId>
  <version>2.0.0</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.11</version>
  <scope>test</scope>
</dependency>
复制代码

Explicaciones relacionadas

// 告诉JUnit使用PowerMockRunner进行测试
@RunWith(PowerMockRunner.class) 

// 所有需要测试的类列在此处,适用于模拟final类或有final, private, static, native方法的类
@PrepareForTest({RandomUtil.class}) 

//忽略的程序包中的类(不加载指定包); 常用于解决使用powermock后,提示classloader错误
@PowerMockIgnore("javax.management.*") 

// 创建一个实例,这个实例可以调用真实代码的方法
@InjectMocks

// 创建了一个全部Mock的实例,所有属性和方法全被置空(0或者null)。
@Mock
复制代码

valor de retorno simulado

// mock期望值
1. PowerMockito.doReturn(expected).when(mockList).get(index);
2. PowerMockito.when(mockList.get(index)).thenReturn(expected);

// mock异常返回
1. PowerMockito.doThrow(new IndexOutOfBoundsException()).when(mockList).get(index);
2. PowerMockito.when(mockList.get(index)).thenThrow(new IndexOutOfBoundsException());

// 无返回值
PowerMockito.doNothing().when(mockList).clear();

//注意:when().thenReturn()模式会执行原方法,而doReturn().when()模式不会执行原方法。

复制代码

devolución de cheques

Mockito.verify(mockList).clear(); //验证是否方法被调用

Mockito.verify(mockList, Mockito.times(1)).clear(); //验证方法的调用次数

复制代码

parámetro simulado

Mockito proporciona Mockito.anyInt(), Mockito.anyString, Mockito.any(Class clazz), etc. para representar valores arbitrarios.

Cuando usamos comparadores de parámetros, todos los parámetros deben usar comparadores. Si desea especificar un valor específico para un parámetro, debe usar el método Mockito.eq().

ejemplo

Para diferentes clases o métodos de burla.

------MockMapper.class
public interface MockMapper {
  public int count(MockModel model);

}

-----MockServiceImpl.class
@Service
public class MockServiceImpl {
  @Autowired
  private MockMapper mockMapper;

  public int count(MockModel model) {
    return mockMapper.count(model);
  }
    
    public boolean makeFile(String path) {
       File file = new File(path);
       return file.exists();
    }
}

------MockUtil.class
public class MockUtil {
    private static final Random random = new Random();
    
    public static int nextInt(int bound) {
        return random.nextInt(bound);
    }
}

复制代码

método normal simulado

@RunWith(PowerMockRunner.class) 
@PrepareForTest({MockUtil.class}) 
@PowerMockIgnore("javax.management.*")
public class MockExample {
    // 将@Mock注解的示例注入进来
    @InjectMocks
    private MockServiceImpl mockService;
    @Mock
    private MockMapper mockMapper;
    
    /**
     * mock普通方法
     */
    @Test
    public void testSelectAppAdvertisementList() {
        MockModel model = new MockModel();
        PowerMockito.when(mockMapper.count(model)).thenReturn(2);
        Assert.assertEquals(2, mockService.count(model));
    }
}
复制代码

Método estático simulado

  1. declaración:
PowerMockito.mockStatic(Class clazz);
PrepareForTest({Class clazz});
复制代码
  1. usar
@RunWith(PowerMockRunner.class) 
@PrepareForTest({MockUtil.class}) 
@PowerMockIgnore("javax.management.*")
public class MockStaticExample {
  @Test 
  public void testStaticMethod() { 
    PowerMockito.mockStatic(MockUtil.class); 
    PowerMockito.when(MockUtil.nextInt(10)).thenReturn(7); 
    Assert.assertEquals(7, MockUtil.nextInt(10)); 
  }
}
复制代码

Constructor dentro del método simulado

  1. declaración
  • Construir pasando parámetros especificados
PowerMockito.whenNew(*.class).withArguments(argument1, ...).thenReturn(file)
复制代码
  • Construir independientemente de los parámetros
PowerMockito.whenNew(*.class).withAnyArguments().thenReturn(file)
复制代码
  1. usar
public final class FileUtils {

    public static boolean isFile(String fileName) {
        return new File(fileName).isFile();
    }

}

----UT
@RunWith(PowerMockRunner.class)

@PrepareForTest({FileUtils.class})
public class MockStructureExample {
    @Test
    public void testIsFile() throws Exception {
        String fileName = "test.txt";
        File file = PowerMockito.mock(File.class);
        PowerMockito.whenNew(File.class).withArguments(fileName).thenReturn(file);
        PowerMockito.when(file.isFile()).thenReturn(true);
        Assert.assertTrue("返回值为假", FileUtils.isFile(fileName));
    }
}
复制代码

Algunos métodos de espionaje de clase simulada

Si un objeto, solo queremos simular algunos de sus métodos y queremos que otros métodos sean iguales al original, puede usar el método PowerMockito.spy en lugar del método PowerMockito.mock. Por lo tanto, el método establecido por la declaración when llama al método simulado, y el método que no está establecido por la declaración when llama al método original.

  1. declaración:
PowerMockito.spy(Class clazz); // 类
T PowerMockito.spy(T object); //spy对象
复制代码
  1. usar

Ejemplo 1

public class StringUtils {

    public static boolean isNotEmpty(final CharSequence cs) {
        return !isEmpty(cs);
    }
    
    public static boolean isEmpty(final CharSequence cs) {
        return cs == null || cs.length() == 0;
    }
}

----UT
@RunWith(PowerMockRunner.class)
@PrepareForTest({ StringUtils.class })
public class StringUtilsTest {

    @Test
    public void testIsNotEmpty() {
        String string = null;
        boolean expected = true;
        PowerMockito.spy(StringUtils.class);
        PowerMockito.when(StringUtils.isEmpty(string)).thenReturn(!expected);
        boolean actual = StringUtils.isNotEmpty(string);
        Assert.assertEquals("返回值不相等", expected, actual);
    }

}
复制代码

Ejemplo 2 objeto espía

public class UserService {

    private Long superUserId;

    public boolean isNotSuperUser(Long userId) {
        return !isSuperUser(userId);
    }

    public boolean isSuperUser(Long userId) {
        return Objects.equals(userId, superUserId);
    }
}

---- UT
@RunWith(PowerMockRunner.class)
public class UserServiceTest {

    @Test
    public void testIsNotSuperUser() {
        Long userId = 1L;
        boolean expected = false;
        UserService userService = PowerMockito.spy(new UserService());
        PowerMockito.when(userService.isSuperUser(userId)).thenReturn(!expected);
        boolean actual = userService.isNotSuperUser(userId);
        Assert.assertEquals("返回值不相等", expected, actual);
    }

}
复制代码

clase de sistema simulado

Nota: dado que la clase URLEncoder es una clase de sistema, debemos preparar SystemClassUser para la prueba, ya que esta es la clase URLEncoder que llama al método de codificación. Ejemplo 1

public class SystemClassUser {

	public String performEncode() throws UnsupportedEncodingException {
		return URLEncoder.encode("string", "enc");
	}
}

---UT
@RunWith(PowerMockRunner.class)
@PrepareForTest( { SystemClassUser.class })
public class SystemClassUserTest {

	@Test
	public void assertThatMockingOfNonFinalSystemClassesWorks() throws Exception {
		mockStatic(URLEncoder.class);

		expect(URLEncoder.encode("string", "enc")).andReturn("something");
		replayAll();

		assertEquals("something", new SystemClassUser().performEncode());

		verifyAll();
	}
}
复制代码

Ejemplo 2

public class AppShell {
  public Process exec(String command) {
    return Runtime.getRuntime().exec(command);
  }
}

----UT
@RunWith(PowerMockRunner.class)
@PrepareForTest(AppShell.class)
public class AppShellTest {

    @Mock private Runtime mockRuntime;

    @Test
    public void test() {
        PowerMockito.mockStatic(Runtime.class);

        when(Runtime.getRuntime()).thenReturn(mockRuntime);
        when(mockRuntime.exec()).thenReturn("whatever you want");

        // do the rest of your test
    }
}
复制代码

Métodos privados y propiedades de las clases simuladas.

  1. declaración:
  • burlarse de la propiedad privada
// 第一种方式; 原生JUnit进行单元测试时使用
ReflectionTestUtils.setField(obj, fieldName, value);
// 第二种方式;Whitebox.setInternalState powermock时使用
Whitebox.setInternalState(obj, fieldName, value);
复制代码
  • simulacro de método privado
1. PowerMockito.stub(PowerMockito.method(UserService.class, "isSuperUser", Long.class)).toReturn(!expected);
2. PowerMockito.when(userService, "isSuperUser", userId).thenReturn(!expected);
复制代码
  1. usar
@Service
public class UserService {

    @Value("${system.userLimit}")
    private Long userLimit;

    public Long getUserLimit() {
        return userLimit;
    }
    
    private boolean isSuperUser(Long userId) {
        return Objects.equals(userId, superUserId);
    }

}

-----UT
public class UserServiceTest {

    @Autowired
    private UserService userService;

    // mock 私有属性
    @Test
    public void testGetUserLimit() {
        Long expected = 1000L;
        ReflectionTestUtils.setField(userService, "userLimit", expected);
        // or 下面这一种
        // Whitebox.setInternalState(userService, "userLimit", expected);
        Long actual = userService.getUserLimit();
        Assert.assertEquals("返回值不相等", expected, actual);
    }
    // mock 私有方法
    @Test
    public void testIsNotSuperUser() throws Exception {
        Long userId = 1L;
        boolean expected = false;
        UserService userService = PowerMockito.spy(new UserService());
        PowerMockito.when(userService, "isSuperUser", userId).thenReturn(!expected);
        PowerMockito.stub(PowerMockito.method(UserService.class, "isSuperUser", Long.class)).toReturn(!expected);
        boolean actual = userService.isNotSuperUser(userId);
        Assert.assertEquals("返回值不相等", expected, actual);
    }

}
复制代码

Link de referencia

github.com/powermock/p…

Supongo que te gusta

Origin juejin.im/post/6950490313123168292
Recomendado
Clasificación