春季注入:@MockBean @Repository未注入

时间:2018-10-25 14:51:51

标签: spring spring-boot spring-test

我正在尝试@MockBean一个带有注释的班级@Repository

@Repository
public interface ApplicationDao extends MongoRepository<Application, String> {}

我将其注入到@Service注释的类中:

@Service
public class AuthorizationService {

    private ApplicationDao appsDao;
    private List<Application> allowedApplications;

    @Autowired
    public AuthorizationService(ApplicationDao appsDao) {
        this.appsDao = appsDao;   //<<MOCKED INJECTED BEAN>>
        this.fillApplications();
    }

    private void fillApplications() {
        this.appsDao.findAll()    //<<MOCKED method>>
           .forEach(entry -> {
            this.allowedApplications.put(entry.getName(), entry);
        });
    }

    public bool isAuthorized(Application application) {
        return this.allowedApplications
          .stream()
          .anyMatch(app -> app.getId().equals(application.getId()));
    }
}

我的测试模拟配置如下:

@RunWith(SpringRunner.class)
@SpringBootTest()
public class GroupReferencesTest {

    private @Autowired AuthorizationService;
    private @MockBean ApplicationDao applicationDao;

    @Before
    public void setUp() {

        Application testApplication = new Application();
        testApplication.setName("test-application");
        List<Application> allowedApplications = new ArrayList<Application>();
        allowedApplications.add(testApplication);

        Mockito
            .when(this.applicationDao.findAll())
            .thenReturn(allowedApplications);
    }

    @Test
    public void test() {
        Application app = new Application();
        app.getId("test-application"); 
        assertTrue(this.authorizationService.isAuthorized(app));  //<<FAILS>>
    }
}

尽管如此,我的模拟对象未注入。我的意思是,当我的AuthorizationService调用其注入的ApplicationDao时,它返回一个空列表,而不是我的模拟列表。

我也尝试使用@MockBean(name="applicationDao")。行为是相同的。

我还尝试使用以下代码配置模拟的bean:

@TestConfiguration
public class RestTemplateTestConfiguration {

    @Bean("applicationDao")
    @Primary
    public static ApplicationDao mockApplicationDao() {
        ApplicationDao mock = Mockito.mock(ApplicationDao.class);

        Application testApplication = new Application();
        testApplication.setName("test-application");
        List<Application> allowedApplications = new ArrayList<Application>();
        allowedApplications.add(testApplication);

        Mockito
            .when(mock.findAll())
            .thenReturn(allowedApplications);

        return mock;
    }
}

但是,它不能正常工作。

Application类是:

public class Application {
    private String id;

    //setters & getters
}

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

第一件事-测试类型。答:单元测试。

您正在启动管理AuthorizationService生命周期的Spring上下文,然后尝试注入模拟。真正发生的是,Spring IoC容器正在向ApplicationDao注入一个真实的AuthorizationService(由Spring IoC容器管理的容器)。

解决方案:

由测试跑步者管理AuthorizationService的生命周期(例如MockitoJUnitRunner并向其中注入ApplicationDao模拟)

@RunWith(MockitoJUnitRunner.class)
public class GroupReferencesTest {

    private @InjectMocks AuthorizationService authorizationService;
    private @Mock ApplicationDao applicationDao;

    @Before
    public void setUp() {

        Application testApplication = new Application();
        testApplication.setName("test-application");
        List<Application> allowedApplications = new ArrayList<Application>();
        allowedApplications.add(testApplication);

        Mockito
            .when(this.applicationDao.findAll())
            .thenReturn(allowedApplications);
    }

    @Test
    public void test() {
        Application app = new Application();
        app.getId("test-application"); 
        assertTrue(this.authorizationService.isAuthorized(app));
    }
}

答案 1 :(得分:1)

工作示例

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {AuthorizationService.class})
public class GroupReferencesTest {

    @Autowired
    private AuthorizationService;

    @MockBean
    private ApplicationDao applicationDao;

    @Test
    public void test() {
        //given
        Mockito.when(applicationDao.findAll()).thenReturn(emptyList());

        //when & then
        assertTrue(authorizationService.isAuthorized(app));
    }
}