Java白盒测试
spring单元测试
环境正常单元测试
spring单元测试公共源码类
step1:工程依赖配置
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.25.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.6.0</version>
</dependency>
step2:@ContextConfiguration
位置:spring-test.jar / org.springframework.test.context
作用:加载配置文件用来做测试(加载applicationContext.xml)
属性:
@AliasFor("locations")
String[] value() default {};
@AliasFor("value")
String[] locations() default {};
Class<?>[] classes() default {};
String name() default "";
例子:
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
step3:@RunWith
位置:junit.jar / org.junit.runner
作用:@RunWith是运行器,通过value设定的类来进行单元测试(运行测试类中的测试方法)
属性:
Class<? extends Runner> value()
例子:
@RunWith(value = SpringJUnit4ClassRunner.class)
step4:SpringJUnit4ClassRunner类
位置:spring-test.jar / org.springframework.test.context.junit4
作用:@RunWith是运行器,通过value设定的SpringJUnit4ClassRunner来进行单元测试
相关类:
JUnit4ClassRunner类,BlockJUnit4ClassRunner类,只能运行非spring项目的测试类
SpringJUnit4ClassRunner类是对spring项目的测试类进行单元测试的
总结
@ContextConfiguration是初始化环境,@RunWith是运行器基于刚初始化完成的环境让SpringJUnit4ClassRunner对测试类的@Test方法进行测试
spring项目做单元测试为什么不用testng,是因为testng做单元测试的类是抽象类,我们用不了
Controller层单元测试
单测准备
MockMvc类
位置:spring-test.jar / org.springframework.test.web.servlet
作用:支持spring MVC测试,相关的类有MockMvcRequestBuilders、MockMvcResultMatchers、MockMvcBuilders
源码:
MockMvc(TestDispatcherServlet servlet, Filter[] filters, ServletContext servletContext)
void setDefaultRequest(RequestBuilder requestBuilder)
void setGlobalResultMatchers(List<ResultMatcher> resultMatchers)
void setGlobalResultHandlers(List<ResultHandler> resultHandlers)
public ResultActions perform(RequestBuilder requestBuilder)
MockMvcBuilders类
作用:MockMvc生成器
源码:
public static DefaultMockMvcBuilder webAppContextSetup(WebApplicationContext context)
public static StandaloneMockMvcBuilder standaloneSetup(Object... controllers)
例子
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
@RunWith(value = SpringJUnit4ClassRunner.class)
@WebAppConfiguration
public class UserControllerLoginTest {
@Autowired
private WebApplicationContext context;
private MockMvc mockMvc;
@Before
public void before() {
mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
}
}
单测开发
MockMvcRequestBuilders类
作用:RequestBuilder接口对象生成器
源码:
public static MockHttpServletRequestBuilder get(URI uri)
public static MockHttpServletRequestBuilder post(URI uri)
public static MockHttpServletRequestBuilder put(URI uri)
public static MockHttpServletRequestBuilder patch(URI uri)
public static MockHttpServletRequestBuilder delete(URI uri)
public static MockHttpServletRequestBuilder options(URI uri)
public static MockHttpServletRequestBuilder head(URI uri)
public static MockHttpServletRequestBuilder request(String httpMethod, URI uri)
MockHttpServletRequestBuilder类
作用:此类下的方法都与发送请求有关
源码:
public MockHttpServletRequestBuilder secure(boolean secure)
public MockHttpServletRequestBuilder characterEncoding(String encoding)
public MockHttpServletRequestBuilder content(String content)
public MockHttpServletRequestBuilder contentType(String contentType)
public MockHttpServletRequestBuilder header(String name, Object... values)
public MockHttpServletRequestBuilder param(String name, String... values)
public MockHttpServletRequestBuilder params(MultiValueMap<String, String> params)
public MockHttpServletRequestBuilder cookie(Cookie... cookies)
ResultActions接口
作用:获取结果
源码:
ResultActions andExpect(ResultMatcher matcher)
ResultActions andDo(ResultHandler handler)
MvcResult andReturn()
andReturn()方法结合Junit的Assert类也可以做断言但是相对繁琐,所以我们选择andExpect(ResultMatcher matcher)和andDo(ResultHandler handler)方法结合使用
MockMvcResultMatchers类
作用:基于ResultMatcher的结果操作的静态工厂方法
源码:
public static StatusResultMatchers status()
public static HeaderResultMatchers header()
public static ContentResultMatchers content()
public static JsonPathResultMatchers jsonPath(String expression, Object... args)
public static CookieResultMatchers cookie()
MockMvcResultHandlers类
作用:基于ResultHandler的结果操作的静态工厂方法
源码:
public static ResultHandler log()
public static ResultHandler print()
MvcResult接口
作用:提供对已执行请求结果的访问
源码:
MockHttpServletRequest getRequest()
MockHttpServletResponse getResponse()
例子
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.cookie;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
@RunWith(value = SpringJUnit4ClassRunner.class)
@WebAppConfiguration
public class UserControllerLoginTest {
@Autowired
private WebApplicationContext context;
private MockMvc mockMvc;
private static final String REQ_URL = "/user/login.html";
private static final String CONTENT_TYPE = "application/json;charset=UTF-8";
private static final String SUCCESS_BODY = "{\"name\":\"zhangsan\",\"pwd\":\"123456\"}";
private static final String JSONPATH_CODE = "$.code";
private static final Integer JSONPATH_CODE_SUCCESS_VALUE = 200;
private static final String JSONPATH_MSG = "$.msg";
private static final String JSONPATH_MSG_SUCCESS_VALUE = "登录成功";
private static final String JSESSIONID = "JSESSIONID";
@Before
public void before() {
mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
}
@Test
public void testLoginSuccess() throws Exception {
String timestamp = String.valueOf(System.currentTimeMillis());
String sign = SignUtil.getSign(timestamp);
success(request(timestamp, sign, SUCCESS_BODY));
}
public ResultActions request(String timestamp, String sign, String body) throws Exception {
ResultActions rs = mockMvc.perform(post(REQ_URL)
.contentType(CONTENT_TYPE)
.header("timestamp", timestamp)
.header("sign", sign)
.content(body));
return rs;
}
public void success(ResultActions rs) throws Exception {
rs.andDo(print());
rs.andExpect(status().isOk());
rs.andExpect(jsonPath(JSONPATH_CODE).value(JSONPATH_CODE_SUCCESS_VALUE));
rs.andExpect(jsonPath(JSONPATH_MSG).value(JSONPATH_MSG_SUCCESS_VALUE));
rs.andExpect(cookie().exists(JSESSIONID));
}
}
单测报告
jacoco报告
认识:jacoco(java code Coverage)是一个java开源的覆盖率工具,并可与maven,eclipse,sonar,Jenkins等结合使用
作用:mvn test执行单元测试时,用jacoco插件生成单元测试结果和覆盖率
配置:pom.xml
<properties>
<jacoco.version>0.8.7</jacoco.version>
<argLine>-Dfile.encoding=utf-8</argLine>
</properties>
<build>
<finalName>spring</finalName>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>default-report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/coverage-reports</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
解读
类覆盖率:被测class类文件是否被覆盖
方法覆盖率:被测的方法是否被覆盖
分支覆盖率:被测程序的if和switch语句的分支是否被覆盖(绿色全覆盖,红色无覆盖,黄色部分覆盖)
行覆盖率:被测的每行代码是否被覆盖
instruction覆盖率:字节码有关,分支越多,按行统计覆盖率和按instruction统计覆盖率数据有差异;反之无分支或分支少两者数据相等或接近
单测总结
A.准备测试环境
B.MockMvc创建
C.MockMvc.perform执行请求
D.ResultActions.andExpect添加执行完成后断言
E.ResultActions.andDo添加结果处理器
F.优化代码
G.单元测试报告
Service层单元测试
场景一
单测–controller–service–dao
此场景不用做service层单测,因当前单测代码向controller层代码发请求,会覆盖service和dao层代码
场景二
当前阶段代码只有service–dao
需对service层代码做单测
步骤:
A.准备linux测试环境
B.公共源码类开发(启动spring项目环境)
C.@Autowired导入service层对象
D.@Test代码开发
E.单元测试报告
例子
@ContextConfiguration(locations= {"classpath:applicationContext.xml"})
@RunWith(value=SpringJUnit4ClassRunner.class)
@WebAppConfiguration
public class UserServiceTest {
private User user = new User();
private static final int DELETE_USER_ID = 2;
private static final int DML_DB_SUCCESS_RESULT = 1;
@Autowired
private UserService userService;
@Test
public void testDeleteUserById() {
user.setId(DELETE_USER_ID);
Assert.assertEquals(userService.deleteUserById(user), DML_DB_SUCCESS_RESULT);
Assert.assertEquals(ObjectUtils.isEmpty(userService.getUser(user.getId())),true);
}
}
环境隔离单元测试
spring单元测试公共源码类
step1:工程依赖配置
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.25.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
step2:@ContextConfiguration
位置:spring-test.jar / org.springframework.test.context
作用:加载配置文件用来做测试
属性:
@AliasFor("locations")
String[] value() default {};
@AliasFor("value")
String[] locations() default {};
Class<?>[] classes() default {};
String name() default "";
例子:
@ContextConfiguration(classes=MockServletContext.class)
step3:@RunWith
位置:junit.jar / org.junit.runner
作用:@RunWith是运行器,通过value设定的类来进行单元测试
属性:
Class<? extends Runner> value()
例子:
@RunWith(value = SpringJUnit4ClassRunner.class)
step4:SpringJUnit4ClassRunner类
位置:spring-test.jar / org.springframework.test.context.junit4
作用:@RunWith是运行器,通过value设定的SpringJUnit4ClassRunner来进行单元测试
Controller层单元测试
单测准备
MockMvc类
位置:spring-test.jar / org.springframework.test.web.servlet
作用:支持spring MVC测试,相关的类有MockMvcRequestBuilders、MockMvcResultMatchers、MockMvcBuilders
源码:
MockMvc(TestDispatcherServlet servlet, Filter[] filters, ServletContext servletContext)
void setDefaultRequest(RequestBuilder requestBuilder)
void setGlobalResultMatchers(List<ResultMatcher> resultMatchers)
void setGlobalResultHandlers(List<ResultHandler> resultHandlers)
public ResultActions perform(RequestBuilder requestBuilder)
MockMvcBuilders类
作用:MockMvc生成器
源码:
public static DefaultMockMvcBuilder webAppContextSetup(WebApplicationContext context)
public static StandaloneMockMvcBuilder standaloneSetup(Object... controllers)
例子
@ContextConfiguration(classes=MockServletContext.class)
@RunWith(value=SpringJUnit4ClassRunner.class)
public class UserControllerMockitoLoginTest {
private MockMvc mockMvc;
@InjectMocks
private UserController userController;
@Mock
private UserService userService;
@Mock
private SignService signService;
@Mock
private SessionService sessionService;
@Before
public void before() {
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders.standaloneSetup(userController).build();
}
}
单测开发
MockMvcRequestBuilders类
作用:RequestBuilder接口对象生成器
源码:
public static MockHttpServletRequestBuilder get(URI uri)
public static MockHttpServletRequestBuilder post(URI uri)
public static MockHttpServletRequestBuilder put(URI uri)
public static MockHttpServletRequestBuilder patch(URI uri)
public static MockHttpServletRequestBuilder delete(URI uri)
public static MockHttpServletRequestBuilder options(URI uri)
public static MockHttpServletRequestBuilder head(URI uri)
public static MockHttpServletRequestBuilder request(String httpMethod, URI uri)
MockHttpServletRequestBuilder类
作用:此类下的方法都与发送请求有关
源码:
public MockHttpServletRequestBuilder secure(boolean secure)
public MockHttpServletRequestBuilder characterEncoding(String encoding)
public MockHttpServletRequestBuilder content(String content)
public MockHttpServletRequestBuilder contentType(String contentType)
public MockHttpServletRequestBuilder header(String name, Object... values)
public MockHttpServletRequestBuilder param(String name, String... values)
public MockHttpServletRequestBuilder params(MultiValueMap<String, String> params)
public MockHttpServletRequestBuilder cookie(Cookie... cookies)
ResultActions接口
作用:获取结果
源码:
ResultActions andExpect(ResultMatcher matcher)
ResultActions andDo(ResultHandler handler)
MvcResult andReturn()
andReturn()方法结合Junit的Assert类也可以做断言但是相对繁琐,所以我们选择andExpect(ResultMatcher matcher)和andDo(ResultHandler handler)方法结合使用
MockMvcResultMatchers类
作用:基于ResultMatcher的结果操作的静态工厂方法
源码:
public static StatusResultMatchers status()
public static HeaderResultMatchers header()
public static ContentResultMatchers content()
public static JsonPathResultMatchers jsonPath(String expression, Object... args)
public static CookieResultMatchers cookie()
MockMvcResultHandlers类
作用:基于ResultHandler的结果操作的静态工厂方法
源码:
public static ResultHandler log()
public static ResultHandler print()
MvcResult接口
作用:提供对已执行请求结果的访问
源码:
MockHttpServletRequest getRequest()
MockHttpServletResponse getResponse()
Mockito相关类
位置: mockito-all.jar / org. mockito
@Mock注解类
作用:模拟1个Mock对象
源码:
String name() default ""
Class<?>[] extraInterfaces() default {}
boolean serializable() default false
@InjectMocks注解类
作用:创建某类的实例对象,@Mock出的对象会被注入到@InjectMocks对象中
MockitoAnnotations类
作用:对mockito注解初始化
源码:
public static void initMocks(Object testClass)
Mockito类
作用:Mockito库支持mock的创建及验证,打桩
源码:
public class Mockito extends Matchers
public static <T> OngoingStubbing<T> when(T methodCall)
public static <T> T verify(T mock)
public static Stubber doAnswer(Answer answer)
public static Stubber doNothing()
public static Stubber doReturn(Object toBeReturned)
public static InOrder inOrder(Object... mocks)
public static Object[] ignoreStubs(Object... mocks)
public static VerificationMode times(int wantedNumberOfInvocations)
public static VerificationMode never()
public static VerificationMode atLeastOnce()
public static VerificationMode atLeast(int minNumberOfInvocations)
public static VerificationMode atMost(int maxNumberOfInvocations)
public static VerificationMode calls( int wantedNumberOfInvocations )
public static VerificationMode only()
public static VerificationWithTimeout timeout(long millis)
public static VerificationAfterDelay after(int millis)
public static MockSettings withSettings()
public static boolean anyBoolean()
public static byte anyByte()
public static char anyChar()
public static int anyInt()
public static long anyLong()
public static float anyFloat()
public static double anyDouble()
public static short anyShort()
public static <T> T anyObject()
public static <T> T anyVararg()
public static <T> T any(Class<T> clazz)
public static <T> T any()
public static String anyString()
public static List anyList()
public static Set anySet()
public static Map anyMap()
public static Collection anyCollection()
public static boolean eq(boolean value)
public static byte eq(byte value)
public static char eq(char value)
public static double eq(double value)
public static float eq(float value)
public static int eq(int value)
public static long eq(long value)
public static short eq(short value)
public static <T> T eq(T value)
public static <T> T refEq(T value, String... excludeFields)
public static <T> T same(T value)
public static Object isNull()
public static Object notNull()
public static Object isNotNull()
public static String contains(String substring)
public static String matches(String regex)
public static String endsWith(String suffix)
public static <T> T argThat(Matcher<T> matcher)
public static char charThat(Matcher<Character> matcher)
public static boolean booleanThat(Matcher<Boolean> matcher)
public static byte byteThat(Matcher<Byte> matcher)
public static short shortThat(Matcher<Short> matcher)
public static int intThat(Matcher<Integer> matcher)
public static long longThat(Matcher<Long> matcher)
public static float floatThat(Matcher<Float> matcher)
public static double doubleThat(Matcher<Double> matcher)
例子
@ContextConfiguration(classes=MockServletContext.class)
@RunWith(value=SpringJUnit4ClassRunner.class)
public class UserControllerMockitoLoginTest {
private MockMvc mockMvc;
private static final String REQ_URL = "/user/login";
private static final String CONTENT_TYPE = "application/json;charset=UTF-8";
private static final String SUCCESS_BODY = "{\"name\":\"zhangsan\",\"pwd\":\"123456\"}";
private static final String JSONPATH_CODE = "$.code";
private static final Integer JSONPATH_CODE_SUCCESS_VALUE = 200;
private static final String JSONPATH_MSG = "$.msg";
private static final String JSONPATH_MSG_SUCCESS_VALUE = "登录成功";
private static final boolean SIGN_HANDLER_SUCCESS_VALUE= true;
private static final long USERSERVICE_CONT_ROW_SUCCESS_VALUE= 1;
private static final String SESSIONSERVICE_ADDSESSION_SUCCESS_VALUE= "OK";
@InjectMocks
private UserController userController;
@Mock
private UserService userService;
@Mock
private SignService signService;
@Mock
private SessionService sessionService;
@Before
public void before() {
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders.standaloneSetup(userController).build();
}
@Test
public void testLoginSuccess() throws Exception {
mockServiceRs(SIGN_HANDLER_SUCCESS_VALUE,USERSERVICE_CONT_ROW_SUCCESS_VALUE,SESSIONSERVICE_ADDSESSION_SUCCESS_VALUE);
String timeStamp = String.valueOf(System.currentTimeMillis());
String sign = SignUtil.getSign(timeStamp);
success(request(timeStamp,sign,SUCCESS_BODY));
}
public void mockServiceRs(boolean handlerRs,Long countRow,String addSessionRs) {
when(signService.handler(any())).thenReturn(handlerRs);
when(userService.CountRowByNamePwd(any())).thenReturn(countRow);
when(sessionService.addSession(anyString(), any())).thenReturn(addSessionRs);
}
public ResultActions request(String timestamp, String sign, String body) throws Exception {
ResultActions rs = mockMvc.perform(post(REQ_URL)
.contentType(CONTENT_TYPE)
.header("timestamp", timestamp)
.header("sign", sign)
.content(body));
return rs;
}
public void success(ResultActions rs) throws Exception {
rs.andDo(print());
rs.andExpect(status().isOk());
rs.andExpect(jsonPath(JSONPATH_CODE).value(JSONPATH_CODE_SUCCESS_VALUE));
rs.andExpect(jsonPath(JSONPATH_MSG).value(JSONPATH_MSG_SUCCESS_VALUE));
}
}
总结
1、模拟环境的controller的单测,测试完毕后;一定要等service,dao开发完后,再继续做单测因模拟环境测试深度是有限的(只是测了controller层的代码)
2、需要注意的就是contentType格式转换问题,因为是环境隔离测试所以不会加载MVC的配置文件,所以我们需要修改UserController中的接口地址(将.html去掉),并且需要配置pom.xml文件依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.9</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.9</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.9</version>
</dependency>
单测总结
A.公共源码类的开发
B.@InjectMocks模拟controller层对象
C.@Mock模拟service层对象
D.@Before初始化让mock生效
E.@Test开发单测用例(Mockito, Mockmvc)
F.代码优化
G.单元测试报告
Service层单元测试
单测开发
service–dao X mysql
解决问题思路
1.等mysql搭建完成,测试顺序mockmvc-controller--service--dao
2.对dao打桩, service调用dao即是人工干预的结果,测试顺序service--dao
例子
@ContextConfiguration(classes=MockServletContext.class)
@RunWith(value=SpringJUnit4ClassRunner.class)
public class UserServiceMockitTest {
private User user = new User();
private static final int DELETE_USER_ID = 2;
private static final int DML_DB_SUCCESS_RESULT = 1;
@InjectMocks
private UserServiceImpl userServiceImpl;
@Mock
private UserMapper userMapper;
@Before
public void before() {
MockitoAnnotations.initMocks(this);
}
@Test
public void testDeleteUserById(){
user.setId(DELETE_USER_ID);
when(userMapper.deleteById(user)).thenReturn(1);
Assert.assertEquals(userServiceImpl.deleteUserById(user), DML_DB_SUCCESS_RESULT);
}
}
单测总结
需对service层代码做单测,当前阶段代码只有service--dao
步骤:
A.准备linux测试环境
B.公共源码类开发(启动spring项目环境)
C.@InjectMocks模拟接口实现类对象
D.@Mock模拟mapper层对象
E.@Before初始化让mock生效
F.@Test开发单测用例(Mockito)
G.测试报告
普通类单元测试
测试前提
pom. xml配置junit,testng,mockito-all,jacoco
单测方式
junit单测
场景1:代码类已开发完的单测
例子
public class RequestUtilTest {
@Test
public void testSendGet() throws Exception {
String url = "https://ip/xxx/getinfo.html";
String param = "pid=1";
String rs = RequestUtil.sendGet(url, param);
Assert.assertEquals("200", JSONPath.read(rs, "$.respCode"));
Assert.assertEquals("thinkpad", JSONPath.read(rs, "$.respMsg"));
Assert.assertEquals(8000, JSONPath.read(rs, "$.respPrice"));
}
@Test
public void testSendPost() throws Exception {
String url = "http://ip/xxx/loginCheck";
String param = "id=123456&passwd=123456";
String rs = RequestUtil.sendPost(url, param);
Assert.assertEquals("1", JSONPath.read(rs, "$.stateCode"));
Assert.assertEquals("管理员登录成功", JSONPath.read(rs, "$.msg"));
}
}
场景2:被测代码类调用其他类或第三方接口
例子
类调用类-特定场景难模拟数据单测
@RunWith(value=MockitoJUnitRunner.class)
public class AlarmTest {
@Mock
AirTemperature airTemperature;
@InjectMocks
Alarm alarm;
@Test
public void testAlarmCase1() {
when(airTemperature.getDegrees()).thenReturn(7);
Assert.assertEquals("防寒", alarm.info());
}
@Test
public void testAlarmCase2() {
when(airTemperature.getDegrees()).thenReturn(35);
Assert.assertEquals("防暑", alarm.info());
}
@Test
public void testAlarmCase3() {
when(airTemperature.getDegrees()).thenReturn(15);
Assert.assertEquals("正常", alarm.info());
}
}
类调用第三方接口单测
@RunWith(PowerMockRunner.class)
@PrepareForTest({RequestUtil.class})
@PowerMockIgnore({"javax.net.ssl.*"})
public class OrderPayTest {
@InjectMocks
private OrderPay orderPay;
@Before
public void before() {
mockStatic(RequestUtil.class);
}
@Test
public void testStatusSuccess() throws Exception {
when(RequestUtil.sendPost(anyString(), anyString()))
.thenReturn("{\"msg\":\"Success\",\"state\":\"200\"}");
Assert.assertEquals(true, orderPay.status(1, 30));
}
@Test
public void testStatusFail() throws Exception {
when(RequestUtil.sendPost(anyString(), anyString()))
.thenReturn("{\"msg\":\"Fail\",\"state\":\"400\"}");
Assert.assertEquals(false, orderPay.status(2, 30));
}
}
场景3:模拟类集数据
例子
@RunWith(value=MockitoJUnitRunner.class)
public class ClassSetTest {
@Mock
private List list;
@Test
public void testList() {
when(list.get(anyInt())).thenReturn(1,2,3,4,5);
when(list.isEmpty()).thenReturn(false);
}
}
testng单测
场景同junit单测
总结单元测试
1.环境正常单测与环境隔离单测,普通类单测,在企业都用的多
2.单元测试属于白盒测试范畴,集成测试属于灰盒测试范畴,系统测试属于黑盒测试范畴,据金字塔原理测试介入早收益大
3.单元测试分为两部分:人工静态检查法与动态执行跟踪法,原则上开发完代码就要做单元测试,并要覆盖代码各种逻辑分支
|