单元测试的利器-Mockito

442 阅读2分钟

Mockito是一个单元测试框架,能快速的帮助开发者模拟对象里各种方法,它还提供各种校验方法来检测方法是否按照预期执行,我们可以利用它快速对代码逻辑进行单元测试。

本文简单介绍在Junit5下使用Mockito来编写单元测试,这版本下集成Mockito写单元测试更方便,免去了手动声明和注入mock对象,这里简单介绍下使用的基本的配置和例子,方便大家日后在项目中应用。

Junit5配置

首先在Junit5官网上的github example找到maven相关配置 github地址

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.junit</groupId>
				<artifactId>junit-bom</artifactId>
				<version>5.10.1</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<dependencies>
		<dependency>
			<groupId>org.junit.jupiter</groupId>
			<artifactId>junit-jupiter</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<artifactId>maven-surefire-plugin</artifactId>
				<version>3.2.3</version>
			</plugin>
		</plugins>
	</build>

Mockito 配置

我们使用jupiter下的mockito版本,这个包可以更方便的使用注解的方式将mock对象注入。

    <dependency>  
        <groupId>org.mockito</groupId>  
        <artifactId>mockito-junit-jupiter</artifactId>  
        <version>3.9.0</version>  
        <scope>test</scope>  
    </dependency>

单元测试

我们举一个简单的例子来介绍下Mockito,在这个例子中有3个类
User

public class User {

    private String id;

    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

UserDao

public interface UserDao {  
  
    User getById(String id);  
  
    void update(User user);  
}

UserService

public class UserService {

    private UserDao userDao;


    public void updateWithSomeConditions(String userId){
        User user = userDao.getById(userId);
        if (Objects.equals(user.getName(),"xxx")){
            userDao.update(user);
        }
    }

    public UserDao getUserDao() {
        return userDao;
    }

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
}

我们写一个单元测试来测试UserServiceupdateWithSomeConditions方法,这个方法的逻辑很简单,根据userId查询user,如果名字是“xxx”更新。


@ExtendWith(MockitoExtension.class)
class UserServiceTest {

    @Mock
    UserDao userDao;

    @InjectMocks
    UserService userService;

    @Test
    void updateWithSomeConditions() {
        User user = new User();
        user.setId("id");
        user.setName("xxx");
        Mockito.when(userDao.getById(anyString())).thenReturn(user);
        userService.updateWithSomeConditions("id");
        Mockito.verify(userDao,Mockito.times(1)).update(any());
    }
}

@ExtendWith(MockitoExtension.class)
使用该注解可以在JUnit Jupiter测试类中启用Mockito框架的功能,能够在运行时根据Mockito的注解生成mock对象代理,并注入到测试对象里去 比如上面@Mock就会自动创建UserDao的代理对象@InjectMocks会将userService依赖的userDao对象自动注入进去

Mockito最常见的用法就是when()verify()
when()可以mock当对象方法调用时候的行为,比如上面例子中的返回值,也可以模拟抛出异常

Mockito.when(userDao.getById(anyString())).thenThrow(new RuntimeException());

verify()可以校验方法的行为,比如上面例子中是否被调用

详细的用法可以看文档Mockito - mockito-core 5.8.0 javadoc,不在一一解释。