我正在尝试@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
}
有什么想法吗?
答案 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));
}
}