Junit+Mock单元测试

项目用的是maven,所需jar包在pom.xml文件里面配置,单元测试要用的jar具体如下:

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-all</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <scope>test</scope>
        </dependency>

从上面的jar包可以看到,这次主要用了Junit  mock 和 spring-test.

具体的构建项目这里就不多说了,接下来我们直接看下testBean里面的具体代码应用:

具体类:

package com.lcc.parser;

import com.lcc.dto.RatingTagFieldDto;
import com.lcc.rating.RatingTagField;

import java.util.ArrayList;
import java.util.List;

public final class RatingTagFieldDtoParser {

    public static List<RatingTagFieldDto> fromRatingTagFieldList(List<RatingTagField> ratingTagFieldList) {
        if (ratingTagFieldList == null) {
            return new ArrayList<>();
        }

        List<RatingTagFieldDto> resultList = new ArrayList<>();
        for (RatingTagField ratingTagField : ratingTagFieldList) {
            RatingTagFieldDto ratingTagFieldDto = new RatingTagFieldDto();
            ratingTagFieldDto.setId(ratingTagField.getId());
            ratingTagFieldDto.setKey(ratingTagField.getKey());

            resultList.add(ratingTagFieldDto);
        }
        return resultList;
    }

}

测试类:

package com.opentrans.otms.core.infrastructure.service.impl.xtt.rmi.parser;

import com.lcc.dto.RatingTagFieldDto;
import com.lcc.rating.RatingTagField;
import com.opentrans.lcc.rating.RatingTagFieldRepository;
import junit.framework.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import java.util.ArrayList;
import java.util.List;

import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class RatingTagFieldDtoParserTest {
    @Mock
    private RatingTagFieldRepository ratingTagFieldRepository;

    @Before
    public void doBefore() {
        List<RatingTagField> ratingTagFields = mockRatingTagField();
        when(ratingTagFieldRepository.findActiveTags()).thenReturn(ratingTagFields);
    }

    @Test
    public void testFromTatingTagFieldList() {
        List<RatingTagField> ratingTagFields = ratingTagFieldRepository.findActiveTags();
        List<RatingTagFieldDto> ratingTagFieldDtos = RatingTagFieldDtoParser.fromRatingTagFieldList(ratingTagFields);
        RatingTagFieldDto ratingTagFieldDto = ratingTagFieldDtos.get(0);
        Assert.assertEquals(ratingTagFieldDto.getId(), Long.valueOf(111));
        Assert.assertEquals(ratingTagFieldDto.getKey(), "asdfghjkl");
    }

    private List<RatingTagField> mockRatingTagField() {
        List<RatingTagField> ratingTagFields = new ArrayList<>();
        RatingTagField ratingTagField = new RatingTagField();
        ratingTagField.setId(111L);
        ratingTagField.setKey("asdfghjkl");
        ratingTagField.setActive(true);
        ratingTagFields.add(ratingTagField);
        return ratingTagFields;
    }
}

上面的@RunWith注解我们还可以用springJunit4下面的class,只要我们的项目是支持spring的,就可以用
SpringJUnit4ClassRunner.class,但是如果我们用的是SpringJUnit4ClassRunner.class,就必须要加上@ContextConfiguration注解,指向xml文件;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("ConnectionEventMailTest-context.xml")

如果对mock不理解的可以去看一下官方文档;

关于MockitoJUnitRunner.class 和 SpringJUnit4ClassRunner.class 的区别:

Mock下面的类不与数据库进行数据交互,测试类里面的数据是我们纯mock出来的,

而spring下面的类是可以与数据库进行数据交互的,如果我们要进行数据交互就必须指向xml进行数据库连接。

这两个的具体应用要看我们所要写的test类是否需要进行数据库数据交互。

 
号外号外!!!

如果我们的javabean里面的属性是private修饰的,而且还没有get set方法(例如id,如果我们考虑的是自增长或者使用sequnce,我们是不支持对id进行set的),
测试的时候又需要用到id,该怎么办呢?
我们可以用java给我们提供的映射去操作,这个类是Field,在java.lang.reflect下面。
接下来看下具体的代码实现,这段代码是一个工具类下面的一个方法,去给一个class set id;
    public static void setDomainId(Class<?> clazz, Object domain, String key, Object value, boolean isSupperField) {
        try {
            if (isSupperField) {
                clazz = clazz.getSuperclass();
            }
            Field field = clazz.getDeclaredField(key);
            field.setAccessible(true);
            field.set(domain, value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

除了id,其他属性也可以用这个,原理是一样的。

reflectionset get 方法
    public static <T> void reflectionSet(Class<? super T> clazz, T obj, String name, Object value) {
        Field field = null;
        while (!Object.class.equals(clazz)) {
            try {
                field = clazz.getDeclaredField(name);
                break;
            } catch (NoSuchFieldException e) {
                clazz = clazz.getSuperclass();
            }
        }
        try {
            field.setAccessible(true);
            field.set(obj, value);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static <T, R> R reflectionGet(Class<? super T> clazz, T obj, String name) {
        Field field = null;
        while (!Object.class.equals(clazz)) {
            try {
                field = clazz.getDeclaredField(name);
                break;
            } catch (NoSuchFieldException e) {
                clazz = clazz.getSuperclass();
            }
        }

        try {
            field.setAccessible(true);
            return (R) field.get(obj);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

 

 

 

posted @ 2017-07-26 12:06  growthofmonkey  阅读(2922)  评论(0编辑  收藏  举报