我创建的一个方面在直接用于测试方法时不起作用,但在添加到辅助组件时起作用。当我直接使用它时,我怎样才能让它工作。
所以在下面的代码中,testAspect 失败了,但是 testAspectHelper 成功了。
方面内的断点显示代码在失败的测试中未命中,但在通过的测试中命中。
import org.junit.jupiter.api.Test;
import org.opennms.horizon.inventory.SpringContextTestInitializer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.actuate.observability.AutoConfigureObservability;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;
@SpringBootTest
@ContextConfiguration(initializers = {SpringContextTestInitializer.class})
@AutoConfigureObservability
public class AspectTest {
@Autowired
AspectTestHelper aspectTestHelper;
@Test
@WithTenant(tenantId = "Fred")
public void testAspect() {
// Test fails
assert("Fred".equals(TenantContext.getTenantId()));
}
@Test
public void testAspectHelper() {
// Test succeeds
aspectTestHelper.setTenant();
}
}
import org.springframework.stereotype.Component;
@Component
public class AspectTestHelper {
@WithTenant(tenantId = "Alex")
public void setTenant() {
assert("Alex".equals(TenantContext.getTenantId()));
}
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface WithTenant {
String tenantId() default "";
int tenantIdArg() default -1;
String tenantIdArgInternalMethod() default "";
String tenantIdArgInternalClass() default "";
}
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@Component
@Aspect
public class WithTenantAspect {
private static final Logger LOG = LoggerFactory.getLogger(WithTenantAspect.class);
@Autowired
private TenantLookup tenantLookup;
@Around(("@annotation(withTenant)"))
public Object getTenant(ProceedingJoinPoint joinPoint, WithTenant withTenant) throws Throwable {
String tenantId = withTenant.tenantId();
int tenantIdArg = withTenant.tenantIdArg();
String tenantIdArgInternalMethod = withTenant.tenantIdArgInternalMethod();
String tenantIdArgInternalClass = withTenant.tenantIdArgInternalClass();
if (tenantIdArg >= 0) {
Object[] args = joinPoint.getArgs();
if (args.length <= tenantIdArg) {
throw new RuntimeException("TenantIdArg position is greater than the number of arguments to the method");
}
if (tenantIdArgInternalMethod == null || tenantIdArgInternalMethod.isEmpty() || tenantIdArgInternalClass == null || tenantIdArgInternalClass.isEmpty()) {
tenantId = String.valueOf(args[tenantIdArg]);
} else {
Object tenantObj = args[tenantIdArg];
Class clazz = Class.forName(tenantIdArgInternalClass);
Method method = clazz.getMethod(tenantIdArgInternalMethod);
Object tenant = method.invoke(tenantObj);
tenantId = String.valueOf(tenant);
}
}
if (tenantId == null || tenantId.isEmpty()) {
tenantId = tenantLookup.lookupTenantId().orElseThrow();
}
try {
TenantContext.setTenantId(tenantId);
Object proceed = joinPoint.proceed();
return proceed;
} finally {
TenantContext.clear();
}
}
}
Aspect 充当代理,仅当它所设置的函数被另一个类调用时才会触发。如果您在常规类中有一个用 @WithTennant 注释的函数,并从同一类中的另一个函数调用该函数,它也不会触发方面。除非你想直接在你的代码中使用一个实现来测试,否则我不明白你怎么能像你那样没有帮助类。