【发布时间】:2021-09-27 08:34:29
【问题描述】:
到目前为止,我有一个简单的 Java 类,它使用单一方法从数据库中获取数据然后进行一些更新,它看起来像这样:
@Slf4j
@Service
public class PaymentServiceImpl implements PaymentService {
private final PaymentsMapper paymentsMapper;
private final MyProperties myProperties;
public PaymentServiceImpl(PaymentsMapper paymentsMapper,
MyProperties myProperties) {
this.paymentsMapper = paymentsMapper;
this.myProperties = myProperties;
}
@Override
@Transactional
public void doSomething() {
List<String> ids = paymentsMapper.getPaymentIds(
myProperties.getPayments().getOperator(),
myProperties.getPayments().getPeriod().getDuration().getSeconds());
long updated = 0;
for (String id : ids ) {
updated += paymentsMapper.updatedPaymentsWithId(id);
}
}
}
为了记录,MyProperties 类是一个从application.properties 获取属性的@ConfigurationProperties 类,它看起来像这样:
@Data
@Configuration("myProperties")
@ConfigurationProperties(prefix = "my")
@PropertySource("classpath:application.properties")
public class MyProperties {
private Payments payments;
@Getter
@Setter
public static class Payments {
private String operator;
private Period period;
@Getter @Setter
public static class Period{
private Duration duration;
}
}
}
现在我正在尝试为这种方法编写一个简单的测试,我想出了这个:
class PaymentServiceImplTest extends Specification {
@Shared
PaymentsMapper paymentsMapper = Mock(PaymentsMapper)
@Shared
MyProperties properties = new MyProperties()
@Shared
PaymentServiceImpl paymentService = new PaymentServiceImpl(paymentsMapper, properties)
def setupSpec() {
properties.setPayments(new MyProperties.Payments())
properties.getPayments().setOperator('OP1')
properties.getPayments().setPeriod(new MyProperties.Payments.Period())
properties.getPayments().getPeriod().setDuration(Duration.ofSeconds(3600))
}
def 'update pending acceptation payment ids'() {
given:
paymentsMapper.getPaymentIds(_ as String, _ as long) >> Arrays.asList('1', '2', '3')
when:
paymentService.doSomething()
then:
3 * paymentsMapper.updatedPaymentsWithId(_ as String)
}
}
但尝试运行测试我得到一个空指针异常:
java.lang.NullPointerException
at com.example.PaymentServiceImpl.doSomething(PaymentServiceImpl.java:33)
at com.example.service.PaymentServiceImplTest.update pending acceptation payment ids(PaymentServiceImplTest.groovy:33)
谁能告诉我这是为什么?为什么我会在那里获得 NPE?
我对 Spock 的 pom.xml 依赖如下:
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-spring</artifactId>
<scope>test</scope>
</dependency>
【问题讨论】:
-
myProperties.getPayments()是否返回非空值?.getPeriod().getDuration().getSeconds()中的每个调用都有相同的问题。 -
它们都返回
setupSpec()中定义的非空值。问题在于paymentsMapper.getPaymentsIds(),而不是定义的列表返回null。我不知道为什么。