如何使用Mockito模拟方法调用链

时间:2018-04-15 08:08:43

标签: java junit mockito

我有这样的功能:

    @Override
        public ClassA createViewModel(ClassB product, ClassC classCVar)
                throws ModuleException
        {
            ClassA classAVar = ClassA.builder().build();
            try {
                if (product != null && product.getProductData() != null) {

                    String gl_name = product.getProductData().offers().get(0).productCategory().asProductCategory()
                            .inlined().map(ProductCategory::glProductGroup).map(ProductCategory.GLProductGroup::symbol)
                            .orElse("");
                    classAVar.setName = gl_name;

                }
                return classAVar;
            } catch (Exception e) {
                // some lines of code.
            }

我这里有一行像String gl_name = ............ 其中包含一系列方法调用。 现在我想使用Mockito模拟这个函数,并希望从所有这些函数调用中得到最终结果,就像gl_name =" abc&#34 ;;

我该怎么做?

我创建了一个新函数,并将方法调用链放在其中:

public String fetchGLNameFunction(ClassB product)
    {
        String gl_name_result = product.getProductData().offers().get(0).productCategory().asProductCategory()
                .inlined().map(ProductCategory::glProductGroup).map(ProductCategory.GLProductGroup::symbol)
                .orElse("");
        return gl_name_result;
    }

现在我试图创建一个这样的模拟:

@Mock
    private ClassA classAVar;
..........
............

@Test
    public void testfunction1() throws Exception
    {
        when(classAVar.fetchGLNameFromAmazonAPI(classBVar)).thenReturn("abc");

它仍在给我NullPointerException,因为它正在执行我新创建的函数。

2 个答案:

答案 0 :(得分:1)

Mockito中,您需要定义模拟对象的行为。

    //  create mock
    ClassB product = mock(ClassB.class);

    // Define the other mocks from your chain:
    // X, Y, Z, ...

    // define return value for method getProductData()
    when(product.getProductData()).thenReturn(X);
    when(X.offers()).thenReturn(Y);
    when(Y.get(0)()).thenReturn(Z); // And so on.... until the last mock object will return "abc"

答案 1 :(得分:0)

您应该模拟要隔离的依赖项,而不是测试的数据/模型 模拟测试方法的参数将使其更难以阅读,因为您将不得不模拟许多事情。

您的方法链有多个场景,因此通过创建与每个场景对应的B实例作为fixture来测试每个场景。