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

20190711141228183

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

package com.one.util;import lombok.AllArgsConstructor;import lombok.Data;@Data@AllArgsConstructorpublic class Company {    private String name;    public String hh(){        return "字符串";    }}

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

package com.one.util;import lombok.AllArgsConstructor;import lombok.Data;@Data@AllArgsConstructorpublic 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@AllArgsConstructorpublic class Company {    private String name;    public String hh(){        return "字符串";    }}

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

package com.one.util;import lombok.AllArgsConstructor;import lombok.Data;@Data@AllArgsConstructorpublic 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@AllArgsConstructorpublic final class Company {    private String name;    public String hh(){        return "字符串";    }}

User类

package com.one.util;import lombok.AllArgsConstructor;import lombok.Data;@Data@AllArgsConstructorpublic 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

原文链接

收藏 打印