用 Mockito 注入模拟不起作用

新手上路,请多包涵

我正在使用 Mockito 来测试我的 Spring 项目,但是 @InjectMocks 似乎无法将模拟服务注入另一个 Spring 服务(bean)。

这是我要测试的 Spring 服务:

 @Service
public class CreateMailboxService {
    @Autowired UserInfoService mUserInfoService; // this should be mocked
    @Autowired LogicService mLogicService;  // this should be autowired by Spring

    public void createMailbox() {
        // do mething
        System.out.println("test 2: " + mUserInfoService.getData());
    }

}

下面是我想模拟的服务:

 @Service
public class UserInfoService {
    public String getData() {
        return "original text";
    }
}

我的测试代码在这里:

 @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/spring/root-context.xml" })
public class CreateMailboxServiceMockTest {

    @Mock
    UserInfoService mUserInfoService;

    @InjectMocks
    @Autowired
    CreateMailboxService mCreateMailboxService;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void deleteWithPermission() {
        when(mUserInfoService.getData()).thenReturn("mocked text");

        System.out.println("test 1: " + mUserInfoService.getData());

        mCreateMailboxService.createMailbox();
    }
}

但结果会喜欢

test 1: mocked text
test 2: original text  // I want this be "mocked text", too

CreateMailboxService 似乎没有得到模拟的 UserInfoService ,而是使用了 Spring 的自动装配 bean。为什么我的 @InjectMocks 不工作?

原文由 Victor Tsai 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
2 个回答

您可以在 CreateMailboxService 类中为 mUserInfoService 创建 package 级别设置器。

 @Service
public class CreateMailboxService {
    @Autowired UserInfoService mUserInfoService; // this should be mocked
    @Autowired LogicService mLogicService;  // this should be autowired by Spring

    public void createMailbox() {
        // do mething
        System.out.println("test 2: " + mUserInfoService.getData());
    }

    void setUserInfoService(UserInfoService mUserInfoService) {
        this.mUserInfoService = mUserInfoService;
    }
}

然后,您可以使用 setter 在测试中注入该模拟。

 @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/spring/root-context.xml" })
public class CreateMailboxServiceMockTest {

    @Mock
    UserInfoService mUserInfoService;

    CreateMailboxService mCreateMailboxService;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        mCreateMailboxService = new CreateMailboxService();
        mCreateMailboxService.setUserInfoService(mUserInfoService);
    }

    ...
}

这样您就可以避免 @InjectMocks 和 Spring 注释的问题。

原文由 alayor 发布,翻译遵循 CC BY-SA 3.0 许可协议

就我而言,我在使用 JUnit5 时遇到了类似的问题

@ExtendWith(MockitoExtension.class)
class MyServiceTest {
...

@InjectMocks
MyService underTest;

@Test
void myMethodTest() {
...
}

underTest 为空。问题的原因是我使用了 JUnit4 包中的 @Test import org.junit.Test; 而不是 JUnit5 import org.junit.jupiter.api.Test;

原文由 Oleg Ushakov 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题