1. 在项目开发中,我们经常会使用@Value注解从配置文件中注入属性值,在编写单元测试时,在不启动容器的条件下,如何对这种属性进行mock呢?针对这种情况,Spring提供了一个很好的工具类ReflectionTestUtils来实现。
注入属性:

@Service
public class LoginServiceImpl {

    @Value("${config.timeLimit}")
    private int timeLimit;
    
    ......

    public Object login(User user) {
        ...
    }
}

对这个属性,在单元测试中可以这样编写:

@Mock
LoginServiceImpl loginService;

@BeforeMethod(alwaysRun = true)
    public void init () {
        //初始化当前测试类所有Mock注解模拟对象,不初始化会报异常
        MockitoAnnotations.initMocks(this);
    }


@Test
public void testLogin () {

    ReflectionTestUtils.setField(loginService, "timeLimit", 5);
}

顾名思义,该工具类就是利用反射机制来实现的,底层源码如图所示:

public static Field findField(Class < ?>clazz, String name, Class < ?>type) {
    Assert.notNull(clazz, "Class must not be null");
    Assert.isTrue(name != null || type != null, "Either name or type of the field must be specified");
    Class < ?>searchType = clazz;
    while (Object.class != searchType && searchType != null) {
        Field[] fields = getDeclaredFields(searchType);
        for (Field field: fields) {
            if ((name == null || name.equals(field.getName())) && (type == null || type.equals(field.getType()))) {
                return field;
            }
        }
        searchType = searchType.getSuperclass();
    }
    return null;
}

2. 项目中也有通过 environment.getProperty("property") 获取配置文件中的配置项值

@Service
public class LoginServiceImpl {

    @Resource
    Environment environment;    
    
    ......

    public Object login(User user) {
        String name = environment.getProperty("config.name");
    }
}

对于这个属性可以这样设置 when(environment.getProperty("config.name")).thenReturn("tom"); 这样,获取到的值就是设置的那个值

@Mock
LoginServiceImpl loginService;

@Mock
Environment environment;

@BeforeMethod(alwaysRun = true)
    public void init () {
        //初始化当前测试类所有Mock注解模拟对象
        MockitoAnnotations.initMocks(this);
    }

public void testLogin () {

    when(environment.getProperty("config.name")).thenReturn("tom");
}

 

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐