du-*_*-it 0 java arraylist is-empty
在测试中,我向另一个类注入了一个模拟,该类似乎工作正常。但是,当我检查 ArrayList 是否为空时,尽管其长度/大小为 0,结果却为 false。这种情况怎么会发生以及如何解决这个问题?
@Slf4j
@Configuration
@RequiredArgsConstructor
@Setter(onMethod_ = @SuppressFBWarnings({"EI_EXPOSE_REP2", "EI_EXPOSE_REP"}))
@Getter(onMethod_ = @SuppressFBWarnings({"EI_EXPOSE_REP2", "EI_EXPOSE_REP"}))
@EnableConfigurationProperties(MyProperties.class)
public class MyConfig {
private final MyProperties myProperties;
private final GenericApplicationContext applicationContext;
@PostConstruct
void init() {
Objects.requireNonNull(myProperties, "myProperties needs not to be null.");
if (/*myProperties.getApps().size() == 0 || */myProperties.getApps().isEmpty()) {
log.info("bla bla bla");
} else {
...
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的测试课:
@ExtendWith(MockitoExtension.class)
class MyConfigTest {
@Mock
MyProperties myPropertiesMock;
@InjectMocks
MyConfig myConfig;
ApplicationContextRunner contextRunner;
@Test
void should_check_for_empty_apps() {
contextRunner = new ApplicationContextRunner()
.withPropertyValues("foobar.apps[0].name=", "foobar.apps[0].baseUrl=", "foobar.apps[0].basePath=")
;
List apps = Mockito.mock(ArrayList.class);
when(myPropertiesMock.getApps()).thenReturn(apps);
myConfig.init();
contextRunner.run(context -> {
assertThat(apps.size()).isEqualTo(0);
});
}
}
Run Code Online (Sandbox Code Playgroud)
属性类:
@Slf4j
@Validated
@Data
@Setter(onMethod_ = @SuppressFBWarnings({"EI_EXPOSE_REP2", "EI_EXPOSE_REP"}))
@Getter(onMethod_ = @SuppressFBWarnings({"EI_EXPOSE_REP2", "EI_EXPOSE_REP"}))
@ConfigurationProperties(prefix = MyProperties.CONFIG_PREFIX)
public class MyProperties implements LoggableProperties {
public static final String CONFIG_PREFIX = "foobar";
@Valid
@NestedConfigurationProperty
private List<MyEndpoint> apps = new ArrayList<>();
@Data
public static class MyEndpoint {
// @NotNull
// @NotEmpty
private String baseUrl = "";
private String basePath = "";
// @NotNull
// @NotEmpty
private String name = "";
}
}
Run Code Online (Sandbox Code Playgroud)
List apps = Mockito.mock(ArrayList.class);
Run Code Online (Sandbox Code Playgroud)
当您模拟一个类时,它的所有方法体都将被完全丢弃。具有非返回类型的方法void返回该类型的默认值。对于size()that 是 0(默认为int),但对于isEmpty()that 是false(默认为boolean)。
您可以使用spy而不是mock获取您不模拟的方法的实际实现。这也是when(x.method()).thenReturn(y)和doReturn(y).when(x).method()不同的地方。前者实际上调用该方法,但放弃其结果,转而使用模拟的返回值。后者根本不调用该方法(但不是类型安全的)。
您嘲笑数组列表有什么原因吗?我根本没有看到您使用数组列表作为模拟。