void method单测

参考文章:https://blog.knoldus.com/unit-testing-void-methods-with-mockito-and-junit/
https://blog.csdn.net/dongjian764/article/details/17303279
http://www.cocoachina.com/articles/64158

public class ServiceHolder { 
   private final Set<Object> services = new HashSet<Object>();
   public void addService(Object service) {
        services.add(service);
   }
 
    public void removeService(Object service) {
        services.remove(service);
    }
}

我们要测试void addService (…) 这个方法,首先分析它的影响或作用, 它影响的services 这个变量,这个变量是个私有的。 测试这个方法的正确,就要验证services这个变量对象正确性。

如何获取这个私有变量? 我们用mock方法来作。

@Test
public void testAddService() throws Exception {
        ServiceHolder tested = new ServiceHolder();
        final Object service = new Object();

        tested.addService(service);

        // 获得私有变量今昔国内验证
        Set<String> services = Whitebox.getInternalState(tested,"services");

        assertEquals("Size of the \"services\" Set should be 1", 1, services.size());
        assertSame("The services Set should didn't contain the expect service",
                        service, services.iterator().next());
}

Whitebox.getInternalState(tested,"services"); 是powermocker提供的一个方法通过反射获得对象实例。
上面这个例子列出来一个简单的void测试方法, 根据不同的情况可能获取验证对象的方法不同,根据实际情况去考虑。

另外PowerMock 中org.powermock.reflect.Whitebox 类提供了绕过封装的一些方法。可以学习。。。



How to Test void methods

As we already know that our aim is to test void methods in a class but it is also really important to understand why do we test void methods.

Whenever we write unit test cases for any method we expect a return value from the method and generally use assert for checking if the functions return the value that we expect it to return, but in the case of void methods, they do not return any value. So how do we check if our method is functioning properly? Let’s see using an example.

In this example, we are creating Two classes Information and Publishing.

The Information class looks like this:

public class Information {

   private final Publishing publishing;

   public Information(Publishing publishing) {
       this.publishing = publishing;
   }

   public void sendInfoForPublishing(Person person) {
       publishing.publishInformation(person);
   }
}

As we can see the method sendInformationForPublishing() is a void method. The logic for the method is simple. It takes a Person object as a parameter and passes the object to the method of Publishing class.

The method publishInformation() is also a void method.

public class Publishing {

   public void publishInformation(Person person) {
       System.out.println(person);
   }
}

Let us now see how we can write unit test cases for this simple implementation.

Using the verify() method

Whenever we mock a void method we do not expect a return value that is why we can only verify whether that method is being called or not.

Features of verify():

  • Mockito provides us with a verify() method which lets us verify whether the mock void method is being called or not.
  • It lets us check the number of methods invocations. So if the method invocation returns to be zero we would know that our mock method is not being called.

verify(publishing,times(1)).publishInformation(person);

The verify method takes two arguments. The mock method object and the number of invocations you want to verify. The expected number of invocations is passed in the times() method. Let’s see how the test case will look like.

public class InformationTest {

   Publishing publishing = mock(Publishing.class);

   @Autowired
   private Information information;

   @Test
   void whenSendInformationForPublishingIsSuccessful() {
       information = new Information(publishing);
       Person person = ObjectCreator.getPerson();
       doNothing().when(publishing).publishInformation(person);
       information.sendInfoForPublishing(person);
       verify(publishing,times(1)).publishInformation(person);
   }
}

As our function will call the publishInformation() only once so we have passed the value 1 in the times() function. We know that when our test case will call the mocked publishInformation() method, it will not do anything. We need to let Mockito know of this behavior. For this, we use the doNothing() method. Which will in simple terms let Mockito know that it needs to do nothing when the given method is called.
在这里插入图片描述

If we change the number of invocations to any other value the test case should fail.

Here I changed the number of invocations to 2.
在这里插入图片描述



class Elephant extends Animal {   
    public Elephant(String name) {
        super(name);
    }

    void makeNoise() {
        logger.info(" Elephant  make Sound");
    }

    void perform(String day) {
        if (day.equals("thursday") || day.equals("friday")) {
            makeNoise();
        }
    }
}

现在我想测试perform方法.如何使用JUnit对此方法进行单元测试?

最佳答案
与Mockito间谍解决方案

import org.junit.Test;

import static org.mockito.Mockito.*;

public class ElephantTest {

    @Test
    public void shouldMakeNoise() throws Exception {

        //given
        Elephant elephant = spy(new Elephant("foo"));

        //when
        elephant.perform("friday");

        //then
        verify(elephant).makeNoise();

    }
}

否定测试:

@Test
public void elephantShouldDontMakeNoisesOnMonday() {

    //given
    Elephant elephant = spy(new Elephant("foo"));

    //when
    elephant.perform("monday");

    //then
    verify(elephant, never()).makeNoise();

}

要么

@Test
public void shouldDoNotMakeNoisesOnMonday() {

    //given
    Elephant elephant = spy(new Elephant("foo"));

    //when
    elephant.perform("monday");

    then(elephant).should(never()).makeNoise();

}

依赖 org.mockito:mockito-core:2.21.0

猜你喜欢

转载自blog.csdn.net/yangyangrenren/article/details/119458379
今日推荐