mockito 调用真正的方法

mockito Call real methods

我有这个测试: 但是方法 checkIfHold 也被嘲笑

@RunWith(MockitoJUnitRunner.class)
public class FrontSecurityServiceTest {

    @Mock
    private FrontSecurityService frontSecurityService
            = mock( FrontSecurityService.class, withSettings().defaultAnswer(CALLS_REAL_METHODS));

    @Test
    public void test1() {
        when(frontSecurityService.getLoggedInUserId()).thenReturn("000");
        frontSecurityService.checkIfHold(9L);
    }
}

我也试过

   @Mock
    PerService perService;
    @Spy
    private FrontSecurityService frontSecurityService = new FrontOfficeSecurityService(perService);

但不是模拟方法 getLoggedInUserId(),getLoggedInUserId 是 public,非静态和非最终的。

我也试过了,确实可以,但是里面调用了MenService checkIfHold为null

@RunWith(SpringJUnit4ClassRunner.class)
public class FrontSecurityServiceTest {

    @Mock
    MenService menService;
    @Mock
    FrontSecurityService frontSecurityService;
    @Rule
    public MockitoRule rule = MockitoJUnit.rule();


    @Test
    public void test1() {

        MenReturn menReturn1 = MenReturn.builder().build();
        when(menService.getMen(anyString(), anyLong())).thenReturn(Arrays.asList(menReturn1));
         when(frontSecurityService.checkIfHold(anyLong())).thenCallRealMethod();
when(frontSecurityService.getLoggedInUserId()).thenReturn("000");
        frontSecurityService.checkIfHold(9L);
    }

}

我想 @Spy 就是您要找的。尽管如此,测试 FrontSecurityService 并同时模拟它对我来说似乎很奇怪。 请尝试以下操作:

@RunWith(MockitoJUnitRunner.class)
public class FrontSecurityServiceTest {

    @Spy
    private FrontSecurityService frontSecurityService;

    @Test
    public void test1() {
        when(frontSecurityService.getLoggedInUserId()).thenReturn("000");
        frontSecurityService.checkIfHold(9L);
    }
}

理想情况下,对于 FrontSecurityServiceTest,您不应该模拟 FrontSecurityService。那是你的被测系统,你不想测试你的模拟,你想测试你正在测试的系统。

正如我在 上的其他回答中一样,如果您使用 CALLS_REAL_METHODS 进行了模拟,那么您将与您的系统 (FrontSecurityService) 进行交互,但它没有 运行 任何构造函数并且尚未初始化任何字段。 FrontSecurityService 极不可能像那样按预期工作。

, @Spy is what you're looking for. As in the docs, you don't need to call the constructor explicitly, but only because @Spy is documented to do so for you 相同。如果您没有零参数构造函数,@Spy 将要求您调用构造函数,因此调用构造函数并不是一个坏习惯——尤其是当您使用依赖注入框架或某些构造函数稍后可能获得参数的其他上下文。您的 IDE 不理解 Mockito,并且不会检测到正在以反射方式调用构造函数。

一旦你有了 @Spy,事情应该会如你所愿——前提是 getLoggedInUserIdpublic、非 static 和非 final.

我认为第一个问题是您在使用 @Mock 注释的同时还使用了 Mockito.mock(...)。 你可以模拟一个对象,然后告诉 Mockito 哪些方法应该执行真正的实现

尝试以下操作:

@RunWith(MockitoJUnitRunner.class)
public class FrontSecurityServiceTest {

    private FrontSecurityService frontSecurityService = Mockito.mock(FrontSecurityService.class);

    @Test
    public void test1() {
        when(frontSecurityService.getLoggedInUserId()).thenReturn("000");
        when(frontSecurityService.checkIfHold(Mockito.any())).thenCallRealMethod();
        frontSecurityService.checkIfHold(9L);
    }
}

如果 checkIfHold 方法 returns 无效,那么您必须执行如下操作:

Mockito.doCallRealMethod().when(frontSecurityService).checkIfHold(Mockito.any());