我在spring项目中有自定义验证注释。
注释的目的是接受应该是id和dept值的参数名称。
该方面的目的是从注释中获取paramNames,在方法签名中找到相应的参数位置,从识别的位置获取值并使用值执行验证。
这是我到目前为止所写的课程。
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface ValidateDeptAnnotation {
String id();
String dept();
}
在注释方法时执行验证的方面。
@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
}
}
测试类
@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.
}
}
当我运行测试用例时,它在Aspect中的行处失败并显示NullPointerException。
if (annotation.dept().equals(paramterName))
当我调试测试用例时,此处正确获取注释。
PowerMockito.doReturn(annotation).when(mockedMethod).getAnnotation(Mockito.any());
但是,对aspect方法的调用会引发NPE。 任何帮助深表感谢。
提前致谢。
答案 0 :(得分:1)
对于那些徘徊在这种情况下的人。我还没有想出如何解决问题或问题是什么。
我目前已采用这种方法 - 在测试用例中创建反映测试用例的虚拟方法,并正常进行测试用例。
代码:
@RunWith(MockitoJUnitRunner.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();
Method method = myMethod("noMemberId");
Mockito.doReturn(method).when(methodSignature).getMethod();
validationAspect.runValidation(joinPoint);
///...further assertion logic to check for error message
// The test is successful.
}
@ValidateDeptAnnotation(memberId = "",accessToken = "accessToken")
private void noMemberId(String memberId, String accessToken) {}
}
答案 1 :(得分:0)
我目前处于类似的情况,但我相信测试方面包括连接点触发器。我创建了假类并验证了行为&amp;触发我的方面。它使测试更加全面,并验证了连接点的正确性。
以下代码的2条评论:
Ť
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestConfig.class})
public class ValidateDeptAspectTestMockedMethod {
@Autowired
private SampleService sampleService;
@Test
public void testAllWell() {
sampleService.noMemberId("123", "heroquest");
// validation etc..
}
@Test
public void testNopeDidntWork() {
sampleService.noMemberId("123", "heroquest");
// validation etc..
}
@EnableAspectJAutoProxy
public static class TestConfig {
@Bean
public SampleService sampleService() {
// WARNING - SPYING CAN NO LONGER TRIGGER ASPECT BECAUSE OF PROXY
return new SampleService();
}
}
public static class SampleService {
@ValidateDeptAspect(id="789", dept ="dept-789-pacman")
public void noMemberId(String id, String dept) {
// maybe some state you want to save to check after
}
}
}
答案 2 :(得分:0)
当我尝试编写方面的单元测试时,我遇到了同样的情况。 最后,我发现问题是您无法模拟Method类。 您可以通过反射获得方法:
Method method = TestClass.class.getDeclaredMethod("yourMethod");
它可以帮助您获取注释。 希望能有所帮助。