Mockito验证方法调用的顺序/顺序

时间:2014-02-20 07:46:30

标签: java unit-testing mockito

有没有办法验证Mockito中methodOne之前是否有methodTwo被调用?

public class ServiceClassA {
    public void methodOne(){}
 }

public class ServiceClassB {
    public void methodTwo(){}
 }

public class TestClass {
    public void method(){
        ServiceClassA serviceA = new ServiceClassA();
        ServiceClassB serviceB = new ServiceClassB();
        serviceA.methodOne();
        serviceB.methodTwo();
    }
}

5 个答案:

答案 0 :(得分:237)

InOrder可以帮助您做到这一点。

ServiceClassA firstMock = mock(ServiceClassA.class);
ServiceClassB secondMock = mock(ServiceClassB.class);

Mockito.doNothing().when(firstMock).methodOne();   
Mockito.doNothing().when(secondMock).methodTwo();  

//create inOrder object passing any mocks that need to be verified in order
InOrder inOrder = inOrder(firstMock, secondMock);

//following will make sure that firstMock was called before secondMock
inOrder.verify(firstMock).methodOne();
inOrder.verify(secondMock).methodTwo();

答案 1 :(得分:66)

请注意,您还可以使用InOrder类来验证在单个模拟上按顺序调用各种方法,而不仅仅是在两个或更多模拟上。

假设我有两个课程FooBar

public class Foo {
  public void first() {}
  public void second() {}
}

public class Bar {
  public void firstThenSecond(Foo foo) {
    foo.first();
    foo.second();
  }
}

然后我可以添加一个测试类来测试Bar firstThenSecond()方法实际调用first(),然后调用second(),而不是second() },然后first()。请参阅以下测试代码:

public class BarTest {
  @Test
  public void testFirstThenSecond() {
    Bar bar = new Bar();
    Foo mockFoo = Mockito.mock(Foo.class);
    bar.firstThenSecond(mockFoo);

    InOrder orderVerifier = Mockito.inOrder(mockFoo);
    // These lines will PASS
    orderVerifier.verify(mockFoo).first();
    orderVerifier.verify(mockFoo).second();

    // These lines will FAIL
    // orderVerifier.verify(mockFoo).second();
    // orderVerifier.verify(mockFoo).first();
  }
}

答案 2 :(得分:34)

是的,这在文档中有描述。您必须使用InOrder类。

示例(假设已经创建了两个模拟):

InOrder inOrder = inOrder(serviceAMock, serviceBMock);

inOrder.verify(serviceAMock).methodOne();
inOrder.verify(serviceBMock).methodTwo();

答案 3 :(得分:1)

对于 Kotlin 用户,您可以这样做:

class Details(models.Model):
    topicId = models.IntegerField()
    name = models.CharField(max_length=60)
    group = models.CharField(max_length=60, choices = TopicCategory.choices)
    status = models.CharField(max_length=60)


class ChoiceOptions(models.TextChoices):
    YES = 'YES', _('Yes')
    NO = 'NO', _('No')
    NA = 'NA', _('Na')


class MakeAChoice(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    topicId = models.ForeignKey(Details, on_delete=models.CASCADE)
    datetime_made = models.DateTimeField(auto_now_add=True)
    myChoice = models.CharField(max_length=60, choices = ChoiceOptions.choices)




class DetailsSerializer(serializers.ModelSerializer):

    class Meta:
        model = Details
        fields = ('topicId','name','group','status')

class MakeAChoiceSerializer(serializers.ModelSerializer):
    
    class Meta:
        model = MakeAChoice
        fields = ('user','group','datetime_made',mychoice')

}

答案 4 :(得分:0)

使用BDD是

@Test
public void testOrderWithBDD() {


    // Given
    ServiceClassA firstMock = mock(ServiceClassA.class);
    ServiceClassB secondMock = mock(ServiceClassB.class);

    //create inOrder object passing any mocks that need to be verified in order
    InOrder inOrder = inOrder(firstMock, secondMock);

    willDoNothing().given(firstMock).methodOne();
    willDoNothing().given(secondMock).methodTwo();

    // When
    firstMock.methodOne();
    secondMock.methodTwo();

    // Then
    then(firstMock).should(inOrder).methodOne();
    then(secondMock).should(inOrder).methodTwo();


}