如何在要测试的类中模拟抽象类方法

Nih*_*ash 5 java unit-testing junit4 mockito spy

有一个abstract

public abstract class BaseProcessor {
 public BooksTransaction getBooksTransaction() {
        return booksTransaction;
    }
}
Run Code Online (Sandbox Code Playgroud)

还有一个final class要使用Junit进行测试

public final class CreateOrganisationProcessor extends BaseProcessor {

public boolean process() throws Exception { //method to be tested
        request = new CreateOrganisationRequest(IntegrationSystems.valueOf(getBooksTransaction().getSource()),
                IntegrationSystems.valueOf(getBooksTransaction().getDestination()), getBooksTransaction()); 
        request.setRequestTypes(getRequestTypes());
return true;
}
}
Run Code Online (Sandbox Code Playgroud)

我尝试监视BaseProcessor模拟 getBooksTransaction对象的方法return BooksTransaction代码:

@Test
   public void testProcess() throws Exception {
BaseProcessor spy = Mockito.spy(new CreateOrganisationProcessor());
       BooksTransaction booksTransaction = new BooksTransaction();
       booksTransaction.setReferenceID(DEFAULT_REFERENCE_ID);
       Mockito.doReturn(booksTransaction).when(spy).getBooksTransaction();
}
Run Code Online (Sandbox Code Playgroud)

这里,BooksTransaction是一个JPA Entity类。

但是,当我运行测试用例时,模拟似乎不起作用,它不返回对象BooksTransaction。它既不会抛出exception,也不会抛出任何error

我想知道spy这个方法的正确方法,以便它返回一个BooksTransaction按照我的mock.

我是新手Mockito,任何帮助将不胜感激。提前致谢。

Eug*_*ene 1

有趣的是,你对一个甚至无法编译的问题获得了 5 票赞成......我已经简化了一点,这样我就可以实际编译它,因为我不知道你的结构或不能甚至猜对了。

但您应该注意的第一点是默认情况下Mockito不能模拟类;您的问题下有一条评论,说明如何启用该功能。final

@Getter
static abstract class BaseProcessor {
    private BooksTransaction BooksTransaction;
}

@Getter
static class CreateOrganisationProcessor extends BaseProcessor {

    CreateOrganisationRequest request;

    public boolean process() { //method to be tested
        request = new CreateOrganisationRequest(getBooksTransaction());
        return true;
    }

    public CreateOrganisationRequest getRequest() {
        return request;
    }
}


@RequiredArgsConstructor
@Getter
static class BooksTransaction {
    private final String testMe;
}

@Getter
@RequiredArgsConstructor
static class CreateOrganisationRequest {
    private final BooksTransaction booksTransaction;
}
Run Code Online (Sandbox Code Playgroud)

这是一个有效的测试:

@Test
public void test() {
    CreateOrganisationProcessor org = new CreateOrganisationProcessor();
    CreateOrganisationProcessor spy = Mockito.spy(org);
    System.out.println(spy);
    BooksTransaction booksTransaction = new BooksTransaction("go!");

    Mockito.doReturn(booksTransaction).when(spy).getBooksTransaction();

    spy.process();
    BooksTransaction mocked = spy.getRequest().getBooksTransaction();
    Assert.assertEquals(mocked.getTestMe(), "go!");
}
Run Code Online (Sandbox Code Playgroud)

现在想想,你在评论中说://method to be tested但你甚至没有在测试中调用它,听起来很可疑不是吗?该方法是在 中定义的CreateOrganisationProcessor,但您将间谍分配给:

 BaseProcessor spy = Mockito.spy(new CreateOrganisationProcessor());
Run Code Online (Sandbox Code Playgroud)

所以现在你甚至不能process再调用该spy引用,因为它没有BaseProcessor.