38 单元测试
单元测试:针对最小的功能单元编写测试代码,Java程序最小的功能单元是方法,因此,单元测试就是针对Java方法的测试,进而检查方法的正确性
目前测试方法是怎么进行的,存在什么问题:
- 只有一个main方法,如果一个方法的测试失败了,其他方法测试会受到影响
- 无法得到测试的结果报告,需要程序员自己去观察测试是否成功
- 无法实现自动化测试
Junit单元测试框架:JUnit是使用Java语言实现的单元测试框架,它是开源的,Java开发者都应当学习并使用JUnit编写单元测试。此外,几乎所有的IDE工具都继承了JUnit,这样我们就可以直接在IDE中编写并运行JUnit,这样我们就可以直接在IDE中编写并运行JUnit测试,JUnit目前最新版本是。
JUnit优点:
- JUnit可以灵活的选择执行哪些测试方法,可以一键执行全部测试方法。
- Junit可以生成全部方法的测试报告。
- 单元测试中的某个方法测试失败了,不会影响其他测试方法的测试。
UserService.java
//业务方法 public class UserService { public String loginName(String loginName, String passWord){ if("admin".equals(loginName) && "123456".equals(passWord)){ return "登录成功!"; } else{ return "用户名或密码出错!"; } } public void selectNames(){ System.out.println(10/0); System.out.println("查询全部用户名成功!"); } }
TestUserService.java
import org.junit.Assert; import org.junit.Test; //测试类 public class TestUserService { /*测试方法 注意点 1、必须是公开的,无参数,无返回值的方法 2、测试方法必须使用@Test注解标记 */ @Test public void testLoginName(){ UserService userService = new UserService(); String rs = userService.loginName("admin", "123456"); //进行预期结果的正确性测试:断言 Assert.assertEquals("您的功能业务可能出现问题", "登录成功!", rs); } @Test public void testSelectNames(){ UserService userService = new UserService(); userService.selectNames(); } }
import jdk.jfr.BooleanFlag; import org.junit.*; //测试类 public class TestUserService { //修饰实例方法的 @Before public void before(){ System.out.println("===before方法执行一次==="); } @After public void after(){ System.out.println("===after方法执行一次==="); } //修饰静态方法 @BeforeClass public static void beforeClass(){ System.out.println("===beforeClass方法执行一次==="); } @AfterClass public static void afterClass(){ System.out.println("===afterClass方法执行一次==="); } /*测试方法 注意点 1、必须是公开的,无参数,无返回值的方法 2、测试方法必须使用@Test注解标记 */ @Test public void testLoginName(){ UserService userService = new UserService(); String rs = userService.loginName("admin", "123456"); //进行预期结果的正确性测试:断言 Assert.assertEquals("您的功能业务可能出现问题", "登录成功!", rs); } @Test public void testSelectNames(){ UserService userService = new UserService(); userService.selectNames(); } }
===beforeClass方法执行一次=== ===before方法执行一次=== ===after方法执行一次=== ===before方法执行一次=== 5 查询全部用户名成功! ===after方法执行一次=== ===afterClass方法执行一次===
39 动态代理
Star.java
package d9_proxy; public class Star implements Skill{ private String name; public Star(String name){ this.name = name; } @Override public void jump(){ System.out.println(name + "跳舞"); } @Override public void sing(){ System.out.println(name + "唱歌"); } }
Skill接口
package d9_proxy; public interface Skill { void jump(); void sing(); }
StarAgentProxy.java
package d9_proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class StarAgentProxy { //设计一个方法来返回一个明星对象的代理对象 public static Skill getProxy(Star obj){ //为杨超越这个对象,生成一个代理对象 return (Skill) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("收首付款。。。"); //真正的让杨超越去唱歌和跳舞。。。 //method 正在调用的方法对象 args代表这个方法的参数 Object rs = method.invoke(obj, args); System.out.println("收尾款。。。"); return rs; } }); } }
Test.java
package d9_proxy; //目标:学习开发出一个动态代理的对象出来,理解动态代理的执行流程 public class Test { public static void main(String[] args) { //1. 创建一个对象(杨超越) 对象的类必须实现接口 Star s = new Star("杨超越"); // 为杨超越对象,生成一个代理对象(经纪人) Skill s2 = StarAgentProxy.getProxy(s); s2.jump(); s2.sing(); } }
UserService.java
package d10_proxy2; public interface UserService { String login(String loginName, String passWord); void deleteUser(); String selectUsers(); }
UserServiceImpl.java
package d10_proxy2; public class UserServiceImpl implements UserService{ @Override public String login(String loginName, String passWord) { String rs = "登录名和密码错误"; if("admin".equals(loginName) && "123456".equals(passWord)){ rs = "登录成功"; } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return rs; } @Override public void deleteUser() { try { System.out.println("您正在删除用户数据中。。。"); Thread.sleep(2500); } catch (InterruptedException e) { e.printStackTrace(); } } @Override public String selectUsers() { String rs = "查询了10000个用户数据。。。"; try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } return rs; } }
ProxyUtil.java
package d10_proxy2; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class ProxyUtil { //通过一个静态方法,为用户业务对象返回一个代理对象 public static UserService getProxy(UserService obj){ return (UserService) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { long startTime = System.currentTimeMillis(); //真正触发对象的行为执行的 Object rs = method.invoke(obj, args); long endTime = System.currentTimeMillis(); System.out.println(method.getName() + "方法耗时:" + (endTime - startTime) / 1000.0 + "s"); return rs; } }); } }
Test.java
package d10_proxy2; //掌握使用动态代理解决问题,理解使用动态代理的优势 public class Test { public static void main(String[] args) { UserService userService = ProxyUtil.getProxy(new UserServiceImpl()); System.out.println(userService.login("admin", "123456")); System.out.println(userService.selectUsers()); userService.deleteUser(); } }
黑马全套Java教程(十)(二)+https://developer.aliyun.com/article/1556524