繁体   English   中英

测试时自动装配字段为空

[英]Autowired field is null when testing

我正在尝试测试我的应用程序中的一个简单谓词。 这个谓词使用存储库来检查一些数据,但是当我测试它时,存储库总是null ,即使它在实际上下文中运行良好。

这是谓词:

@Slf4j
public class NameChangePredicate implements ValidationPredicate {

    @Autowired
    NameChangeRepository nameChangeRepository;

    String errorCode;
    GeographicZone zone;

    public NameChangePredicate(String errorCode, GeographicZone zone) {
        super();
        this.errorCode = errorCode;
        this.zone = zone;
    }

    /**
     * Test the condition
     *
     * @param response the {@link ValidationServiceResponse}
     * @return true if valid
     */
    @Override
    public boolean test(ValidationServiceResponse response) {
        if (!StringUtils.isBlank(response.getClass()) && zone != null) {
            List<NameChange> nameChanges = nameChangeRepository.findAllByGeographicZoneId(zone.getId());

            if (nameChanges.stream().anyMatch(n -> n.getClasses().stream().anyMatch(response.getClass()::equalsIgnoreCase))) {
                return true;
            }
        }

        throw new ValidationException(this.errorCode);
    }
}

这是我的简单测试:

@ActiveProfiles("test")
@SpringBootTest
public class NameChangeTest {

    @Autowired
    NameChangeRepository nameChangeRepository;

    @Autowired
    GeographicZoneRepository geographicZoneRepository;

    private GeographicZone zone;

    @BeforeEach
    public void init() {
        ....
    }

    @Test
    public void testNameChangeParameter() {
        final NameChangePredicate predicate = new NameChangePredicate("", zone);
        List<NameChange> list = nameChangeRepository.findAll();
        Assert.assertEquals("There should be 4 NameChange in db", 4, list.size());

        ValidationServiceResponse response = new ValidationServiceResponse();
        response.setBookingClass("C");
        Assert.assertTrue("Name change should be eligible", predicate.test(response));
    }
}

但是在测试上下文中, predicate@Autowired存储库为null ,可能是因为它是字段注入。 有没有办法将构造函数注入与其他参数一起使用?

试试这个

@Slf4j
public class NameChangePredicate implements ValidationPredicate {

    String errorCode;
    GeographicZone zone;
    NameChangeRepository nameChangeRepository;

    public NameChangePredicate(String errorCode, GeographicZone zone, NameChangeRepository nameChangeRepository) {
        super();
        this.errorCode = errorCode;
        this.zone = zone;
        this.nameChangeRepository = nameChangeRepository;
    }
...
}

@ActiveProfiles("test")
@SpringBootTest
public class NameChangeTest {

    @Autowired
    NameChangeRepository nameChangeRepository;

    ....

    @Test
    public void testNameChangeParameter() {
        final NameChangePredicate predicate = new NameChangePredicate("", zone, nameChangeRepository);
    }
}

编辑:由于NameChangePredicate不是 Spring @Component本身,因此您需要从充当此类客户端的其他某个组件获取对存储库的引用。 如果您可以将类设计为组件,那么当您“在真实上下文中”运行它时,Spring 会自动将存储库注入构造函数,就像它在测试中自动装配一样。 但当然在这种情况下,您需要以某种方式摆脱构造函数参数errorCodezone ,这在本示例中似乎不太方便。

您在这里混合了两件事:Spring 配置和构造函数。

当您使用构造函数创建NameChangePredicate的实例时,Spring 不工作且未对其进行初始化。

不确定如何更正您的示例,但看起来您的设计不太正确。 NameChangePredicate做两件事:充当谓词并保存两个字段的逻辑。 我建议将这两个字段分开String errorCode; GeographicZone zone; String errorCode; GeographicZone zone; 到一个单独的类,并把它注射在NameChangePredicate以同样的方式为NameChangeRepository

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM