10

私はSpring 4.16を使用しており、メソッドの引数を検証し、何か問題がある場合はValidationExceptionをスローするValidationAspectを持っています。これは、サーバーを実行してリクエストを送信するときに呼び出されますが、テストから来るときは呼び出されません:

package com.example.movies.domain.aspect;
...
@Aspect
public class ValidationAspect {

    private final Validator validator;

    public ValidationAspect(final Validator validator) {
        this.validator = validator;
    }

    @Pointcut("execution(* com.example.movies.domain.feature..*.*(..))")
    private void selectAllFeatureMethods() {
    }

    @Pointcut("bean(*Service)")
    private void selectAllServiceBeanMethods() {
    }

    @Before("selectAllFeatureMethods() && selectAllServiceBeanMethods()")
    public synchronized void validate(JoinPoint joinPoint) {
         // Validates method arguments which are annotated with @Valid
    }
}

アスペクト Bean のアスペクトを作成する構成ファイル

package com.example.movies.domain.config;
...
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AspectsConfiguration {

    @Bean
    @Description("Hibernate validator. Used to validate request's input")
    public Validator validator() {
        ValidatorFactory validationFactory = Validation.buildDefaultValidatorFactory();
        return validationFactory.getValidator();
    }

    @Bean
    @Description("Method validation aspect")
    public ValidationAspect validationAspect() {
        return new ValidationAspect(this.validator());
    }
}

したがって、これはテストです。無効な softwareObject であるため、addSoftware メソッドに入る直前に ValidationException をスローする必要があります。

@ContextConfiguration
@ComponentScan(basePackages = {"com.example.movies.domain"})
public class SoftwareServiceTests {
    private static final Logger LOGGER = LoggerFactory.getLogger(SoftwareServiceTests.class.getName());

    private SoftwareService softwareService;
    @Mock
    private SoftwareDAO dao;
    @Mock
    private MapperFacade mapper;

    @Before
    public void init() {
        MockitoAnnotations.initMocks(this);
        this.softwareService = new SoftwareServiceImpl(this.dao);
        ((SoftwareServiceImpl) this.softwareService).setMapper(this.mapper);

        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SoftwareServiceTests.class);
        ctx.getBeanFactory().registerSingleton("mockedSoftwareService", this.softwareService);
        this.softwareService = (SoftwareService) ctx.getBean("mockedSoftwareService");

    }

    @Test(expected = ValidationException.class)
    public void testAddInvalidSoftware() throws ValidationException {
        LOGGER.info("Testing add invalid software");
        SoftwareObject softwareObject = new SoftwareObject();
        softwareObject.setName(null);
        softwareObject.setType(null);

        this.softwareService.addSoftware(softwareObject); // Is getting inside the method without beeing validated so doesn't throws ValidationException and test fails
    }
}

サービスを実行し、この無効なユーザーを投稿リクエストから追加すると、ValidationException がスローされます。しかし、何らかの理由で、テストレイヤーから ValidationAspect メソッドを実行することはありません

そして私のサービス

package com.example.movies.domain.feature.software.service;
...
@Service("softwareService")
public class SoftwareServiceImpl
    implements SoftwareService {

    @Override
    public SoftwareObject addSoftware(@Valid SoftwareObject software) {
         // If gets into this method then software has to be valid (has been validated by ValidationAspect since is annotated with @Valid)
         // ...
    }
}

mockedSoftwareService Beanは機能パッケージにあり、Bean名は「サービス」で終わるため、アスペクトが呼び出されない理由がわかりません。両方の条件を満たしています。何が起こっている可能性があるかについて何か考えがありますか? 前もって感謝します


編集

@Service("softwareService")
public class SoftwareServiceImpl
    implements SoftwareService {

    private static final Logger LOGGER = LoggerFactory.getLogger(SoftwareServiceImpl.class.getName());

    private SoftwareDAO dao;
    private MapperFacade mapper;

    @Autowired
    private SoftwareCriteriaSupport criteriaSupport;

    @Autowired
    private SoftwareDefaultValuesLoader defaultValuesLoader;

    @Autowired
    public SoftwareServiceImpl(SoftwareDAO dao) {
        this.dao = dao;
    }

    @Autowired
    @Qualifier("domainMapper")
    public void setMapper(MapperFacade mapper) {
        this.mapper = mapper;
    }

   // other methods

}
4

4 に答える 4

8

何をしようとしているのかはわかりませんが、@ContextConfigurationSpring Test を使用してテストを実行していないため、役に立ちません ( @RunWithSpring Test のスーパークラスまたはスーパークラスのいずれかが必要です)。

次に、すでに完全にモック化され、構成されているシングルトンを追加します (これは、コンテキストが想定しているものです)。Spring を回避するのではなく、Spring を使用することを強くお勧めします。

最初に、テスト用のテスト クラス内に構成を作成します。この構成は、スキャンを実行し、モック Bean を登録する必要があります。次に、Spring Test を使用してテストを実行します。

@ContextConfiguration
public class SoftwareServiceTests extends AbstractJUnit4SpringContextTests {
    private static final Logger LOGGER = LoggerFactory.getLogger(SoftwareServiceTests.class.getName());

    @Autowired
    private SoftwareService softwareService;

    @Test(expected = ValidationException.class)
    public void testAddInvalidSoftware() throws ValidationException {
        LOGGER.info("Testing add invalid software");
        SoftwareObject softwareObject = new SoftwareObject();
        softwareObject.setName(null);
        softwareObject.setType(null);

        this.softwareService.addSoftware(softwareObject);
    }

    @Configuration
    @Import(AspectsConfiguration.class)
    public static class TestConfiguration {

        @Bean
        public SoftwareDAO softwareDao() {
            return Mockito.mock(SoftwareDAO.class);
        }

        @Bean
        public MapperFacade domainMapper() {
            return Mockito.mock(MapperFacade.class)
        }

        @Bean
        public SoftwareService softwareService() {
            SoftwareServiceImpl service = new SoftwareServiceImpl(softwareDao())
            return service;
        }

    }
}
于 2015-06-12T07:30:06.903 に答える
1

srping で実行する必要があります:

@EnableAspectJAutoProxy
@RunWith(SpringJUnit4ClassRunner.class)
public class MyControllerTest {

}
于 2021-08-05T02:55:42.820 に答える