@Mock注解就是其实就是用cglib的原理帮我们new了一个@Mock注解作用类的子类,什么意思呢,往下看
首先是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
简单来说上面的代码可以变成下面这样
首先是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
我们可以验证上面的结论
就是给@Mock注解的类添加一个final,然后在运行的时候就报错了
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的规则