zoukankan      html  css  js  c++  java
  • 如何用mockito+spring进行单元测试(2)

    以前写过一篇blog,写得不是很详细。这次清明节在家好好的整理了下思路,把相关的细节重写下来。很奇怪这些内容在google上找不到,也许是太基本了吧。

    为了理解mockito,必须先明白mock测试的原理,它分成以下几个步骤:

    建立mock;
    将mock和待测试的对象连接起来;
    在mock上设置预期的返回值;
    开启replay模式,准备记录实际发生的调用;
    进行测试;
    验证测试结果,调用顺序是否正确,返回值是否符合期望;

    本文主要讲第一步和第二步。

    对于Mockito而言,有两种方式创建:

    • 1. mock为一个interface提供一个虚拟的实现,
    • 2. spy为object加一个动态代理,实现部分方法的虚拟化。

    假设待测试的class声明如下:

    public class Svc{

        DaoInterface dao1;

        DaoInstance dao2;

       …

    你可以用如下的声明得到一个Interface的mock,或者一个实例的spy,并把它注入到测试对象中:

    private Svc svc;
    private DaoInterface mockdao;

    @Before

    public void setup(){

    mockdao = mock(DaoInterface.class);
    svc.setDao1(mockdao);

    }


    private Svc svc;
    private DaoInstance spydao ;

    @Before

    public void setup(){

    tmp= new DaoInstance ();

    spydao = spy(tmp);
    svc.setDao2(spydao);

    }

    请注意到spy和mock的不同。但是spy并不是很好的实践,因为它意味着你的代码不能很好的将变化的部分分离开来。因此最好只在那些历史遗留系统上使用。

    上面这种方式并不唯一的途径。为了避免重复代码,Mockito提供了几个注解:

    @Mock,被标注的属性是个mock

    @Spy,被标注的属性是个spy,需要赋予一个instance

    @InjectMocks,将本test中的mock或者spy注入到被标注的属性中,根据构造函数的参数名,或者setter,或者私有属性名。

    最后在setup中调用MockitoAnnotations.initMocks(this);就免去了代码的编写。如下所示:

    private @InjectMocks Svc svc;
    private @Mock DaoInterface dao1;

    @Before

    public void setup(){

    //mockdao = mock(DaoInterface.class);
    //svc.setDao1(mockdao);

    MockitoAnnotations.initMocks(this);

    }


    private @InjectMocks Svc svc;
    private @Spy DaoInstance dao2=new

    DaoInstance() ;

    @Before

    public void setup(){

    // tmp= new DaoInstance ();

    // spydao = spy(tmp);
    // svc.setDao2(spydao);

    MockitoAnnotations.initMocks(this);

    }

    如果你使用spring,上述代码还可以进一步简化,因为Mockito提供了factory的方法用来创建mock和spy。

    正常的bean声明 <bean id=”svc” class=”Svc”>
    <bean id=”dao1” class=”…”>
    <bean id=”dao2” class=”…”>
    mock

    <bean id="dao1"  class="org.mockito.Mockito" factory-method="mock">
               <constructor-arg value="DaoInterface"></constructor-arg>
    </bean>

    请注意到svc不变化,mock将自动注入进入。这是因为spring的bean容器,如果id一样,后声明的bean会覆盖前面的bean。

    spy

    <bean id="daoInst"  class="DaoInstance">
    </bean>
    <bean id="dao2"  class="org.mockito.Mockito" factory-method="spy">
           <constructor-arg ref="daoInst"></constructor-arg>
    </bean>

    同样svc不变化,直接注入。请注意spy需要获得一个实例。

    然后你只需要对dao1和dao2进行方法设置就可以了。

    Technorati Tags: mockito,spring,mock,spy
  • 相关阅读:
    《Geometric Deep Learning综述介绍》
    《和想象不太一样的'Graph Neural Network + Zero Shot'》
    《几何深度学习前沿》
    《【Paper Live】滴滴出行-探索资源约束的Contextual Bandits问题 & KDD Cup滴滴出行比赛解读>
    《PDP: 解决约束满足问题的神经网络架构 | 刘晶 | 集智俱乐部图网络论文读书会20190819》
    《NeuroSAT: Learning a SAT Solver from Single-Bit Supervision》
    《OR Talk NO.5 | Facebook 田渊栋:用深度(强化)学习为组合优化寻找更好的启发式搜索策略》
    《OR Talk NO.15 | 在业界实验室做AI设计师是一种什么体验?》
    超级跳马 —— 矩阵快速幂优化DP
    图SLAM:Noob的同时本地化和映射指南
  • 原文地址:https://www.cnblogs.com/alphablox/p/3002152.html
Copyright © 2011-2022 走看看