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); } }