mockito/spy不工作,执行原始函数

r9f1avp5  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(418)

我在上课:
gp\u categoryservice.java函数-->

public JSONObject deleteCategory(GP_CategorySubcategoryBean bean) {
        JSONObject data = new JSONObject();
        DirectoryCategoryMaster oCategory = getCategoryMaster(bean);

        if (oCategory.getDirCategoryId() != null) {
            boolean isDeleted = delete(oCategory);
            data.put(ConstantUtil.STATUS, ConstantUtil.SUCCESS);
            data.put(ConstantUtil.DATA, "Category deleted successfully");
        } 
    }

我有两个内部函数调用:
getcategorymaster(bean)
删除(ocategory)
这些基本上都是dao调用,直接更新数据库。现在我想单独模拟这两个函数,这样每当我的测试函数运行时,它都应该返回true。
我编写了以下测试函数:

@Test
    public void deleteCategoryTestDAOV() {
        JSONObject expected = new JSONObject();
        expected.put(ConstantUtil.STATUS, ConstantUtil.SUCCESS);
        expected.put(ConstantUtil.DATA, "Category deleted successfully");

        bean.setCategoryId(1);
        bean.setCategoryName("Test");
        DirectoryCategoryMaster master=new DirectoryCategoryMaster();
        master.setDirCategoryId(1);
        GP_CategoryService mock = spy(new GP_CategoryService());
        when(mock.delete(master)).thenReturn(true);
        when(mock.getCategoryMaster(bean)).thenReturn(master);
        JSONObject actual=new JSONObject();
        actual=mock.deleteCategory(bean);
        assertEquals(expected.toJSONString(), actual.toJSONString());   
    }

但是当我运行测试类时,它执行的是实际的功能,mock不起作用。有人能帮我解决这个问题吗?
提前谢谢!

pcrecxhr

pcrecxhr1#

mockito通过在mock下创建类的cglib代理来工作。例如,如果你 mock(MyClass.class) ,您将获得类的动态代理 MyClass$$EnhancedByMockito$$.class ,延伸 MyClass.class . 因为代理是 MyClass ,生成的类允许用户重写特定的功能(“mock”it)。大多数方法截取都隐藏在幕后,通过易于使用的语句(如 when .
不幸的是,由于java的限制,无法用本机反射代理内部方法调用。这是因为,如果您直接调用示例方法 MyClass:b 从示例方法 MyClass::a ,插入一个扩展 MyClass 执行 MyClass::b 间接地。
从技术上讲,通过一些非常高级的字节码操作(比如bytebuddy)可以做到这一点。
不起作用的示例:

class MyClass {
    public String doSomething() {
        return doSomethingElse();
    }

    public String doSomethingElse() {
        return "foo";
    }
}

// ...

class MyTest {

    private MyClass myClass;

    // ...
    @Test
    void myTest() {
        when(myClass.doSomethingElse()).thenReturn("Bar");
        assertEquals("bar", myClass.doSomething()); // FAILS
    }
}

使用具有可重写方法的中间类时确实有效的示例:

class MyClass {

    private MyClassBackend myClassBackend;

    public MyClass(MyClassBackend myClassBackend) {
        this.myClassBackend = myClassBackend;
    }

    public String doSomething() {
        return myClassBackend.doSomethingElse();
    }
}

class MyClassBackend {
    public String doSomethingElse() {
        return "foo";
    }
}

// ...

class MyTest {

    private MyClass myClass;

    @Mock
    private MyClassBackend myClassBackend;

    @BeforeEach
    void setUp() {
        this.myClass = new MyClass(myClassBackend);
    }

    // ...
    @Test
    void myTest() {
        when(myClassBackend.doSomethingElse()).thenReturn("bar");
        assertEquals("bar", myClass.doSomething()); // PASSES
    }
}

相关问题