Mockito框架里面的@Mock注解原理

  1. 云栖社区>
  2. 博客>
  3. 正文

Mockito框架里面的@Mock注解原理

it乾坤 2019-08-16 15:22:34 浏览433
展开阅读全文

@Mock注解就是其实就是用cglib的原理帮我们new了一个@Mock注解作用类的子类,什么意思呢,往下看

20190711141228183

首先是Company,此时hh方法返回值是”字符串”,

package com.one.util;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class Company {
    private String name;

    public String hh(){
        return "字符串";
    }
}

User类,mm()的返回值就是Company类的hh()返回值

package com.one.util;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class User {
    private  Company company;

    private int age;


    public String mm(){
       return company.hh();
    }
}

然后UserTest类如下,此时可以看到下面的Company上面放了@Mock注解,他的作用就是帮我们生产一个Company类的子类(假如是CompanyZi),然后使用多态赋值给下面的company(就像这样Company company=new CompanyZi),而且这个ComanyZi类里面的hh()方法的返回值是null,为什么这样说呢,我们看下面的结果

package com.one.util;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import static org.assertj.core.api.Assertions.catchThrowable;

@RunWith(MockitoJUnitRunner.class)
public class UserTest {

    @Mock
    private Company company;

    private User user;

    @Before
    public void setUp() {
        user = new User(company, 1);
    }

    @Test
    public void tt() {
        catchThrowable(() -> {
            String mm = user.mm();
            System.out.println(mm);
        });
    }

}

此时可以看到结果是null

20190711141344750

简单来说上面的代码可以变成下面这样

20190711141410267

首先是Company,此时hh方法返回值是”字符串”,

package com.one.util;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class Company {
    private String name;

    public String hh(){
        return "字符串";
    }
}

User类,mm()的返回值就是Company类的hh()返回值

package com.one.util;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class User {
    private  Company company;

    private int age;


    public String mm(){
       return company.hh();
    }
}

然后UserTest类如下,此时下面的类ComapanyZi就相当于上面的被@Mock注解的company的最终被new的对象,只不过@Mock注解帮我做了下面的CompanyZi这个类,此时可以看到下面的ComapanyZi返回的是null

package com.one.util;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import static org.assertj.core.api.Assertions.catchThrowable;

@RunWith(JUnit4.class)
public class UserTest {

    class ComapanyZi extends Company{
        public ComapanyZi(String name) {
            super(name);
        }
        public String hh(){
            return null;
        }
    }
    private User user;

    @Test
    public void name() {
        user=new User(new ComapanyZi("zi"),1);
        Throwable throwable = catchThrowable(() -> {
            System.out.println(user.mm());
        });
    }
}

此时可以看到结果是null

20190711141524966

我们可以验证上面的结论

就是给@Mock注解的类添加一个final,然后在运行的时候就报错了

20190711141543906

Company类,此时可以看到Compan已经被final修改了

package com.one.util;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public final class Company {
    private String name;

    public String hh(){
        return "字符串";
    }
}

User类

package com.one.util;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class User {
    private  Company company;

    private int age;


    public String mm(){
       return company.hh();
    }
}

然后测试如下,然后运行下面的name方法,然后结果如下所示

package com.one.util;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;


@RunWith(MockitoJUnitRunner.class)
public class UserTest {

    @Mock
    private Company company;

    private User user;

    @Before
    public void setUp(){
        user = new User(company,1);
    }

    @Test
    public void name() {
        user.mm();
    }
}

此时可以看到报错了,说Company不能被final修改,者更好符号cglib的规则

20190711141632887

原文链接

网友评论

登录后评论
0/500
评论
it乾坤
+ 关注