Mockito模拟Void方法完全指南:Java单元测试中的无返回值方法处理技巧

大多数情况下,Mockito的when()方法已经足够用来模拟对象的行为。但是,当我们需要模拟一个void方法时,就不能使用when()方法。

使用Mockito模拟void方法

Mockito提供以下方法,可用于模拟void方法。

  1. doAnswer():当调用一个返回void的模拟对象方法时,我们可以使用它来执行一些操作。
  2. doThrow():当我们想对抛出异常的void方法进行存根时,我们可以使用doThrow()方法。

让我们创建一个简单的类,其中有一个void方法,我们将在测试类中进行模拟。

package com.Olivia;

public class Employee {

	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		if (name == null)
			throw new IllegalArgumentException("Employee Name can't be null");
		this.name = name;
	}

}

Mockito的void方法模拟示例

Mockito的doAnswer()方法接受Answer作为参数。它是一个功能性接口,所以我们可以使用lambda表达式来实现它。

doAnswer((i) -> {
	System.out.println("Employee setName Argument = " + i.getArgument(0));
	assertTrue("Pankaj".equals(i.getArgument(0)));
	return null;
}).when(emp).setName(anyString());

请注意,由于我们正在模拟一个void方法,因此需要返回null语句。

使用Mockito模拟带有异常的void方法

以下代码片段展示了如何使用doThrow()方法来模拟带有异常的void方法。

doThrow(IllegalArgumentException.class).when(emp).setName(null);

JUnit Mockito模拟void方法示例

这里有一个使用JUnit的完整示例,我正在使用Mockito模拟一个void方法。

package com.Olivia.mockito.voidmethod;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import org.junit.jupiter.api.Test;

import com.Olivia.Employee;

class JUnitMockitoVoidMethod {

	@Test
	void test_mockito_void() {
		Employee emp = mock(Employee.class);

		doThrow(IllegalArgumentException.class).when(emp).setName(null);

		doAnswer((i) -> {
			System.out.println("Employee setName Argument = " + i.getArgument(0));
			assertTrue("Pankaj".equals(i.getArgument(0)));
			return null;
		}).when(emp).setName(anyString());

		when(emp.getName()).thenReturn("Pankaj");

		assertThrows(IllegalArgumentException.class, () -> emp.setName(null));

		emp.setName("Pankaj");
		assertEquals("Pankaj", emp.getName());
	}

}

TestNG Mockito void方法示例

由于JUnit 5和TestNG注解非常相似,我们不需要在上述类中进行任何特定的代码更改就可以从JUnit 5切换到TestNG。只需删除JUnit 5的导入语句并添加以下导入即可将测试框架从JUnit切换到TestNG。

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertThrows;
import static org.testng.Assert.assertTrue;

import org.testng.annotations.Test;

你可以从我们的GitHub仓库下载完整的项目代码。

bannerAds