package pl.edu.agh.dsm.front.mocks; import static org.mockito.Mockito.*; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.springframework.context.annotation.*; import org.springframework.hateoas.config.EnableEntityLinks; import org.springframework.hateoas.config.EnableHypermediaSupport; import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType; import pl.edu.agh.dsm.front.core.infrastructure.UseCase; import pl.edu.agh.dsm.front.core.model.rest.UserCredentials; import pl.edu.agh.dsm.front.core.model.rest.dto.ComplexMeasurementDto; import pl.edu.agh.dsm.front.core.model.rest.dto.ComplexMeasurementOutDto; import pl.edu.agh.dsm.front.core.usecase.*; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @Configuration @EnableEntityLinks @EnableHypermediaSupport(type = HypermediaType.HAL) @ComponentScan( value = {"pl.edu.agh.dsm.front.web" }, excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, value = UseCase.class)) @Profile("mockComponents") public class MocksConfiguration { @Bean public MeasurementControllerMock controllerMock() { return new MeasurementControllerMock(); } @Bean public MockRepository mockRepository() { return new MockRepository(); } @Bean public MockImplementation mockImplementation() { return new MockImplementation(); } @Primary @Bean public AddMeasurement addMeasurement() throws Exception { return (AddMeasurement) mockUsecase(AddMeasurement.class, "addMeasurement", String.class, ComplexMeasurementOutDto.class, UserCredentials.class); } @Primary @Bean public DeleteMeasurement deleteMeasurement() throws Exception { return (DeleteMeasurement) mockUsecase(DeleteMeasurement.class, "deleteMeasurement", String.class, UserCredentials.class); } @Primary @Bean public GetAvailableComplexTypes getAvailableComplexTypes() throws Exception { return (GetAvailableComplexTypes) mockUsecase(GetAvailableComplexTypes.class, "getAvailableComplexTypes", String.class); } @Primary @Bean public GetMeasurements getMeasurements() throws Exception { return (GetMeasurements) mockUsecase(GetMeasurements.class,"getMeasurements", String.class, String.class, UserCredentials.class); } @Primary @Bean public GetSystemResources getSystemResources() throws Exception { return (GetSystemResources) mockUsecase(GetSystemResources.class, "getResources"); } private Object mockUsecase(Class<?> mockClass, final String mockMethodName, final Class<?> ... argsTypes) throws Exception { Method realMethod = mockClass.getDeclaredMethod(mockMethodName, argsTypes); Object mockObject = mock(mockClass); Object args[] = new Object[argsTypes.length]; for(int i=0; i<args.length; i++) { Class<?> type = argsTypes[i]; args[i] = any(type); } when(realMethod.invoke(mockObject, args)).then(mockAnswer(mockMethodName, argsTypes)); return mockObject; } private Answer mockAnswer(final String mockMethodName, Class<?> ... argsTypes) throws NoSuchMethodException { final Method mockMethod = MockImplementation.class.getDeclaredMethod(mockMethodName, argsTypes); return new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { Object[] args = invocation.getArguments(); return mockMethod.invoke(mockImplementation(), args); } }; } }