Problem with correct class setting for tests.
I have the following service structure
My service:
Interface
public interface ColumnsFromTableService {
List<ColumnsDto> getTableColumnsFromSource(DataProvider dataProvider, String tableName);
DataProviderSourceType myDataProviderSourceType();
@Autowired
default void regMe(ColumnsFromTableFacade columnsFromTableFacade){
columnsFromTableFacade.register(myDataProviderSourceType(),this);
}
}
Impl
@Service
@RequiredArgsConstructor
public class OracleColumnsFromTableServiceImpl implements ColumnsFromTableService {
private final DataProviderInsideDao dataProviderInsideDao;
@Override
public List<ColumnsDto> getTableColumnsFromSource(DataProvider dataProvider, String tableName) {
return dataProviderInsideDao.getColumnsByTableNameFromOracle(dataProvider, tableName);
}
@Override
public DataProviderSourceType myDataProviderSourceType() {
return DataProviderSourceType.ORACLE;
}
}
My facade:
Interface
public interface ColumnsFromTableFacade {
List<ColumnsDto> getTableColumnsFromSource(DataProvider dataProvider, String tableName);
void register(DataProviderSourceType dataProviderSourceType, ColumnsFromTableService columnsDataProviderService);
}
Impl
@Service
public class ColumnsFromTableFacadeImpl implements ColumnsFromTableFacade {
private final Map<DataProviderSourceType, ColumnsFromTableService> implementationMap = new HashMap<>();
@Override
public List<ColumnsDto> getTableColumnsFromSource(DataProvider dataProvider, String tableName) {
ColumnsFromTableService columnsFromTableService = implementationMap.get(dataProvider.getSourceType());
return columnsFromTableService.getTableColumnsFromSource(dataProvider,tableName);
}
@Override
public void register(DataProviderSourceType dataProviderSourceType, ColumnsFromTableService columnsDataProviderService) {
implementationMap.put(dataProviderSourceType, columnsDataProviderService);
}
}
For use, I inject the facade in the place I need.
Everything works in the application. When creating ColumnsFromTableService beans, Spring Boot sees the @Autowired annotation in the interface and and registers the service in the facade. But when testing this facade, I can't set it up correctly.
My test:
@ExtendWith(MockitoExtension.class)
public class EasyServiceTest {
@InjectMocks
TablesFromSourceFacadeImpl tablesFromSourceFacade;
@Test
void test(){
tablesFromSourceFacade.getAllTablesFromSource(new DataProvider());
}
}
When running the test, the facade is successfully instantiated. But the collection with implementations is empty.
I am using Junit jupiter - 5.7.1 Spring boot - 2.4.3
CodePudding user response:
you have not provided class source code for TablesFromSourceFacadeImpl
. So, its difficult to say what beans that class is expecting. but, in general, check this article to understand how @InjectMocks
works: https://www.baeldung.com/mockito-annotations
all the beans that you class TablesFromSourceFacadeImpl
requires must be declared and mock instances using @Mock
annotation. The effect is, all the @Autowired
beans are wired with Mock instance that you have reference to in you test file and thus are available for stubbing.
CodePudding user response:
I decided to be rough
@ExtendWith(MockitoExtension.class)
public class EasyServiceTest {
TablesFromSourceFacadeImpl tablesFromSourceFacade;
@InjectMocks
OracleTablesFromSourceServiceImpl oracleTablesFromSourceService;
@InjectMocks
OracleColumnsFromTableServiceImpl oracleColumnsFromTableService;
@BeforeEach
void setUp() {
tablesFromSourceFacade = new TablesFromSourceFacadeImpl();
tablesFromSourceFacade.register(postgresTablesFromSourceService.myDataProviderSourceType(),
postgresTablesFromSourceService);
tablesFromSourceFacade.register(oracleTablesFromSourceService.myDataProviderSourceType(),
oracleTablesFromSourceService);
}
@Test
void test(){
tablesFromSourceFacade.getAllTablesFromSource(new DataProvider());
}
}