De manière standard :
@RestController
public class Main {
UserService userService;
public Main(){
userService = new UserServiceImpl();
}
@GetMapping("/")
public String index(){
return userService.print("Example test");
}
}
Interface de service aux utilisateurs :
public interface UserService {
String print(String text);
}
Classe UserServiceImpl :
public class UserServiceImpl implements UserService {
@Override
public String print(String text) {
return text + " UserServiceImpl";
}
}
Sortie : Example test UserServiceImpl
C'est un excellent exemple de classes étroitement couplées, un mauvais exemple de conception et il y aura des problèmes avec les tests (PowerMockito est également mauvais).
Voyons maintenant l'injection de dépendances de SpringBoot, un bel exemple de couplage souple :
L'interface reste la même,
Classe principale :
@RestController
public class Main {
UserService userService;
@Autowired
public Main(UserService userService){
this.userService = userService;
}
@GetMapping("/")
public String index(){
return userService.print("Example test");
}
}
Classe ServiceUserImpl :
@Component
public class UserServiceImpl implements UserService {
@Override
public String print(String text) {
return text + " UserServiceImpl";
}
}
Sortie : Example test UserServiceImpl
et maintenant il est facile d'écrire des tests :
@RunWith(MockitoJUnitRunner.class)
public class MainTest {
@Mock
UserService userService;
@Test
public void indexTest() {
when(userService.print("Example test")).thenReturn("Example test UserServiceImpl");
String result = new Main(userService).index();
assertEquals(result, "Example test UserServiceImpl");
}
}
J'ai montré @Autowired
sur le constructeur mais elle peut aussi être utilisée sur le setter ou le champ.