Counting method invocations in Unit tests

2019-04-17 19:18发布

What is the best way to count method invocations in a Unit Test. Do any of the testing frameworks allow that?

7条回答
仙女界的扛把子
2楼-- · 2019-04-17 19:46

In Mockito you can do something like this:

YourService serviceMock = Mockito.mock(YourService.class);

// code using YourService

// details of all invocations including methods and arguments
Collection<Invocation> invocations = Mockito.mockingDetails(serviceMock).getInvocations();
// just a number of calls of any mock's methods
int numberOfCalls = invocations.size();
查看更多
来,给爷笑一个
3楼-- · 2019-04-17 19:52

You can count number of method invocation by using interface Answer in Mockito.

ConnectionPool mockedConnectionPool = mock(ConnectionPool.class);

    final int[] counter = new int[1];

    when(mockedConnectionPool.getConnection()).then(new Answer<Connection>() {

        @Override
        public Connection answer(InvocationOnMock invocation) throws Throwable {
            counter[0]++;
            return conn;
        }

    }); 
    // some your code

    assertTrue(counter[0] == 1);
查看更多
看我几分像从前
4楼-- · 2019-04-17 19:52

Depending on what methods you want to count, you can create a test config, with a @Before advice matching your class / package / method:

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class MethodCounterAspect {

    private int counter = 0 // or inject the Counter object into this aspect

    @Pointcut( "execution( * com.sample.your.package.*.*(..) )" )
    public void methodsToCount() {}

    @Before("methodsToCount()")
    public void execute() throws Throwable {
        counter++; // or update the counter injected into this aspect..
    }

    // get the counter
}

You can use vanilla AspectJ or Spring AOP via above or XML configs if you find it easier.

You can create different pointcuts / aspect if you need to.

查看更多
5楼-- · 2019-04-17 20:01

It sounds like you may want to be using the .expects(1) type methods that mock frameworks usually provide.

Using mockito, if you were testing a List and wanted to verify that clear was called 3 times and add was called at least once with these parameter you do the following:

List mock = mock(List.class);        

someCodeThatInteractsWithMock();                 

verify(mock, times(3)).clear();
verify(mock, atLeastOnce()).add(anyObject());      

(From http://code.google.com/p/mockito/wiki/MockitoVSEasyMock)

查看更多
Luminary・发光体
6楼-- · 2019-04-17 20:04

It sounds like you may want a test spy. See, for example, Mockito.spy().

查看更多
我命由我不由天
7楼-- · 2019-04-17 20:05

You've got a few options

1) Add some special code which counts invocations in the function. It will work, but it's not a great solution.

2) After you run your unit tests, check the code coverage. Most coverage tools will count invocations but they are really designed for post-processing.

3) Use a profiler. A profiler will let you count how many times a function is invoked. This is a very manual process so it's not really designed for unit testing.

A better solution would be to check that output is what you expect rather than checking how it works internally.

查看更多
登录 后发表回答