J'ai une annotation de validation personnalisée dans un projet Spring.
L'objectif de l'annotation est d'accepter les noms des paramètres qui sont censés être des valeurs id et dept.
Le but de l'aspect est de récupérer les noms de paramètres de l'annotation, de trouver la position du paramètre correspondant dans la signature de la méthode, d'obtenir les valeurs des positions identifiées et d'effectuer la validation avec les valeurs.
Voici les cours que j'ai écrits jusqu'à présent.
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface ValidateDeptAnnotation {
String id();
String dept();
}
L'aspect qui effectue la validation lorsqu'une méthode est annotée.
@Aspect
@Component
public class ValidateDeptAspect {
@Before("@annotation(<package>.ValidateDeptAnnotation)")
public void runValidation(JoinPoint joinPoint) throws MemberIdentityException {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
ValidateDeptAnnotation annotation = method.getAnnotation(ValidateDeptAnnotation.class);
String id = null;
String dept = null;
for (int index = 0; index < signature.getParameterNames().length; index++) {
String paramterName = signature.getParameterNames()[index];
if (annotation.dept().equals(paramterName)) {
dept = joinPoint.getArgs()[index].toString();
} else if (annotation.id().equals(paramterName)) {
id = joinPoint.getArgs()[index].toString();
}
}
//....further processing...throw appropriate error msgs logic
}
}
La classe de test
@RunWith(PowerMockRunner.class)
@PrepareOnlyThisForTest({Method.class})
public class ValidateDeptAspectTestMockedMethod {
@InjectMocks
private ValidateDeptAspect validationAspect;
@Mock
private JoinPoint joinPoint;
@Mock
private MethodSignature methodSignature;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
@Test
public void testIdParamNotFound() {
String[] methodSignatureParams = {"id","dept"};
String[] argumentValues= {"789","dept-789-pacman"};
Mockito.doReturn(methodSignature).when(joinPoint).getSignature();
Mockito.doReturn(methodSignatureParams).when(methodSignature).getParameterNames();
Mockito.doReturn(argumentValues).when(joinPoint).getArgs();
ValidateDeptAnnotation annotation = Mockito.mock(ValidateDeptAnnotation.class);
Method mockedMethod = PowerMockito.mock(Method.class);
Mockito.doReturn(mockedMethod).when(methodSignature).getMethod();
PowerMockito.doReturn(annotation).when(mockedMethod).getAnnotation(Mockito.any());
// PowerMockito.when(mockedMethod.getAnnotation(ValidateDept.class)).thenReturn(annotation); --didnot work, same error.
Mockito.doReturn("iiiiid").when(annotation).id();
Mockito.doReturn("dept").when(annotation).dept();
validationAspect.runValidation(joinPoint);
///...further assertion logic to check for error message as iiiid != id
//but never gets here.
}
}
Lorsque j'exécute le scénario de test, il échoue avec NullPointerException à la ligne dans l'Aspect.
if (annotation.dept().equals(paramterName))
Lorsque je débogue le scénario de test, l'annotation est obtenue correctement ici.
PowerMockito.doReturn(annotation).when(mockedMethod).getAnnotation(Mockito.any());
Cependant, l'appel à la méthode d'aspect génère un NPE. Toute aide est la bienvenue.
Merci d'avance.