UT和PowerMock

PowerMock 简介

要测试的方法会引用很多外部依赖的对象(获得连接getConnection,getAdmin),外部对象不可控,模拟(mock)外部对象使其可控。

核心思想

你要mock的方法必须是你mock的对象调的。原有的对象只会走原有的逻辑。

什么情况需要加注解:

@RunWith(PowerMockRunner.class)
@PrepareForTest ( { YourClassWithEgStaticMethod.class })
  1. PowerMockito.whenNew方法时,注解@PrepareForTest里写的类是需要mock的new对象代码所在的类
  2. 普通对象的finil方法,注解里写filal方法所在的类
  3. 普通对象的static方法,注解里写static方法所在的类
PowerMockito.mockStatic(ClassDependency.class);
PowerMockito.when(ClassDependency.isExist()).thenReturn(true);
  1. private方法,注解里private方法所在类
PowerMockito.when(other.pub(Mockito.anyString())).thenCallRealMethod();
PowerMockito.when(other, "pri", Mockito.anyString()).thenReturn(" $$ I am handsome %% private.");
  1. 系统类的静态和final方法,注解里写的类是需要调用系统方法所在的类

其他

  1. Void方法 不用加注解,but:
PowerMockito.doNothing().when(mockUnder.dovoid(Mockito.anyString()));   //WRONG
PowerMockito.doNothing().when(mockUnder).dovoid(Mockito.anyString());   //RIGHT
PowerMockito.doNothing().when(mockUnder,"dovoid","aa","bb");   //RIGHT
PowerMockito.when(mockUnder,"dovoid","aa","bb").thenAnswer(answer);   //RIGHT

推荐以下的写法,因为使用范围比较广

PowerMockito.doNothing().when(mockUnder,"dovoid","aa","bb");
PowerMockito.doNothing().when(UnderTest.class,"dovoid","aa","bb");
PowerMockito.when(mockUnder,"dovoid","aa","bb").thenAnswer(answer);
PowerMockito.when(under1, "isDpa", Mockito.anyString()).thenReturn(true);
  1. Spy
    类C的m1方法掉了m2,想覆盖类C的m1,模拟打桩m2
    可以考虑用spy
  2. Answer
    Object[] args = invocation.getArguments();
    注意传入的参数,不要越界
  3. 希望多次返回结果不同,比如第一次返回true,第二次false
    PowerMockito.when(under1.isDpa(Mockito.anyString())).thenReturn(true).thenReturn(false);
  4. Mock 抛异常
    PowerMockito.doThrow(new NullPointerException()).when(other).doExcep(Mockito.anyString());
    抛的异常必须是mock的方法可能抛的,否则mock会抛异常
    所以不要在测试用例的大catch里写Assert.assertTrue(true);来判断程序抛异常,因为这个异常很可能是mock的时候就抛了。
    @Test
    public void test() 
    {
        try
        {
            // do some test
        }
        catch (Exception e)
        {
            e.printStackTrace();
            Assert.assertTrue(false);
        }
    }
  1. 反射
UnderTest under = new UnderTest();
StudentMgr stuMgr = PowerMockito.mock(StudentMgr.class);
Class<AbstractClass> clazz = AbstractClass.class;
Field field = clazz.getDeclaredField("studentMgr");
field.setAccessible(true);
field.set(under, stuMgr);

常见问题

  1. InitializationError
    @Test 注解没加
    缺jar包
    Junit 版本不对(junit不能用4.12)
  2. spy() vs mock()

spy() is used when you want the real code of the class you are spying on to do its job, but be able to intercept method calls and return values. mock() is used to make a new class that has the same interface as the class you are mocking, but with NO code inside...

注意事项

  1. UT结束清理环境
    @BeforeClass        //测试class前
    public static void setUpBeforeClass() throws Exception
    {
    }
    @AfterClass     //测试class前
    public static void tearDownAfterClass() throws Exception
    {
    }
    @Before     //每个Test前
    public void setUp() throws Exception
    {
    }
    @After      //每个Test后
    public void tearDown() throws Exception
    {
    }
  1. setUp()中mock的东西会影响到每个Test
    注意:

mock singleton static final : mock before other code new it.
mock单例要在其他代码new它前

  1. 测试的目的
    发现代码的缺陷,发现问题,及时与开发确认,不要只为了覆盖率去写测试。
    能全流程尽量全流程
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,790评论 25 707
  • 本文介绍了Android单元测试入门所需了解的内容,包括JUnit、Mockito和PowerMock的使用,怎样...
    于卫国阅读 4,562评论 0 5
  • Instrumentation介绍 Instrumentation是个什么东西? Instrumentation测...
    打不死的小强qz阅读 7,771评论 2 39
  • 背景 在写单元测试的过程中,一个很普遍的问题是,要测试的目标类会有很多依赖,这些依赖的类/对象/资源又会有别的依赖...
    johnnycmj阅读 1,157评论 0 3
  • 跋山涉水做了四个半小时的车程来到了美丽的山城,心情确并不美丽,开会加班,晚上只睡了一个半小时,点了杯美美的冰饮,不...
    Universe_Eva阅读 226评论 0 0