Breaking a local dependency to unit test a void method

梦想的初衷 提交于 2019-12-04 15:43:14

Your worker creates his own factory class here:

private VodkaFactory vodkaFactory = new VodkaFactory();

The mock you are creating is completely detached from the worker instance and thus the lack of interaction. To make it work, factory has to be injected to worker from "the outside", say via constructor injection.

If this is legacy code, you could use reflection to replace private factory instance with mocked one.

As noted by JB Nizet in comment, your mock setup comes after work is already called. In order to make things right, inject mock and set it up before you call any code utilizing it.

You need to set your vodkaFactory:

@Test
public void
does_the_worker_drink_while_working() {
    VodkaFactory vodkaFactory = mock(VodkaFactory.class);
    Vodka vodka = mock(Vodka.class);
    Worker worker = new Worker();
    when(vodkaFactory.getVodka()).thenReturn(vodka);

    //call your setter        
    worker.setVodkaFactory(vodkaFactory);

    worker.work();
    verify(vodka,times(1)).drink();
}

It is more comment than an answer. In addition to make factory an injectable dependency, you can also make sure to train your mock when(vodkaFactory.getVodka()).thenReturn(vodka); before interacting with it worker.work();

There is a logical error in the code you are trying to test. Because you have created VodkaFactory instance inside of the Worker class and moreover you have made that field private.

The best solution would be to pass a reference to VodkaFactory from outside of the class.

public class Worker {          

    private VodkaFactory vodkaFactory;

    public void work() {
                   Vodka vodka = vodkaFactory.getVodka();
                   vodka.drink();
     }

     public void setVodkaFactory(VodkaFactory vf) {
           vodkaFactory = vf;
     }

}

Now, in your @Test you can pass your mocked VodkaFactory instance using setVodkaFactory setter.

The following is a complete JMockit unit test which exercises the Worker#work() method in isolation from the implementation of its Vodka dependency:

@Test
public void workTest(@Mocked final Vodka mockBeverage)
{
    new Worker().work();

    new Verifications() {{ mockBeverage.drink(); times = 1; }};
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!