【发布时间】:2019-03-09 21:33:54
【问题描述】:
我有一个奇怪的案例,我想测试“某些”功能而不触及另一个……我很难选择合适的描述,我希望我将在下面展示的代码几乎是自我描述的。
假设我有一个保留一些策略的类:
class TypeStrategy {
private static final CreateConsumer CREATE_CONSUMER = new CreateConsumer();
private static final ModifyConsumer MODIFY_CONSUMER = new ModifyConsumer();
private static final Map<Type, Consumer<ConsumerContext>> MAP = Map.of(
Type.CREATE, CREATE_CONSUMER,
Type.MODIFY, MODIFY_CONSUMER
);
public static void consume(Type type, ConsumerContext context) {
Optional.ofNullable(MAP.get(nodeActionType))
.orElseThrow(strategyMissing(type))
.accept(context);
}
}
想法很简单——有一些策略是为某个Type注册的;方法consume 将简单地尝试找到一个正确的注册类型并使用提供的ConsumerContext 在其上调用consume。
现在的问题是:我非常想测试我关心的所有策略是否都已注册,我可以在它们上调用accept - 这就是我想要测试的全部内容。
通常,我会在TypeStrategy 上使用@SuppressStaticInitializationFor,而使用WhiteBox::setInternalState 只会为CREATE_CONSUMER 和MODIFY_CONSUMER 添加我需要的任何内容;但在这种情况下我不能,因为MAP 也会被跳过,我真的不希望这样,我只关心这两个策略 - 我需要 MAP保持原样。
除了一些令人讨厌的重构之外,这确实让我达到了我想成为的地方,我不知道如何才能实现这一目标。在最好的情况下,我希望@SuppressStaticInitializationFor 支持一些“部分”跳过,您可以在其中指定一些过滤器来确定您想要跳过的内容,但这不是一个选项,真的。
我还可以测试调用链上的“所有内容”——即测试 accept 应该做的所有事情,但这会在此测试中增加近 70 行模拟,理解这一点将成为一场噩梦它真的想测试一个很小的部分。
【问题讨论】:
-
如何为您的消费者提供mocking the constructors,并检查与他们的互动?
-
@Morfic 这确实是答案,如果你用一个小例子来回答,会很高兴接受它