我正在试驾一些练习代码并发现奇怪的情况。
有一个ChannelRegistry包含所有通信通道引用,并且当调用initialize()时,需要将自身附加到其中一个通道的PrimaryConsumer在运行时选择。 所以我完成了我的第一次测试如下:
@RunWith(MockitoJUnitRunner.class)
public class PrimaryConsumerTest {
private @Mock ChannelsRegistry communicationRegistry;
private PrimaryConsumer consumer;
@Before
public void setup() {
consumer = new PrimaryConsumer(communicationRegistry);
}
@Test
public void shouldAttachToChannel() throws Exception {
consumer.initialize();
verify(communicationRegistry).attachToChannel("channel", consumer);
}
}
我正在检查是否调用了附加方法。为了让它变绿,我把这样的impl:
public void initialize() {
communicationRegistry.attachToChannel("channel", this);
}
现在接下来的测试:按名称获取频道ID并附加到此特定频道。我希望我的测试能够描述类的行为而不是内部因素,所以我不希望我的测试成为“shouldGetSpecificChannel”。相反,我检查它是否可以附加到运行时选择的通道:
@Test
public void shouldAttachToSpecificChannel() throws Exception {
String channelName = "channel";
when(communicationRegistry.getChannel("channel_name")).thenReturn(channelName);
consumer.initialize();
verify(communicationRegistry).attachToChannel(channelName, consumer);
}
此测试立即通过,但执行被搞砸(“频道”硬编码)。
这里有2个问题:
对这种行为进行2次测试是否可以?也许我应该在第一次测试中立即获取通道?如果是这样,它如何映射到单个测试中测试单个东西?
如何应对这种情况:测试绿色,impl“硬编码”?我应该用不同频道的名字写另一个测试吗?如果是这样,我应该在纠正impl之后将其删除(因为它无用吗?)
更新 只是一些澄清。 我在这里硬编码“频道”
public void initialize() {
communicationRegistry.attachToChannel("channel", this);
}
只是为了让第一次测试快速通过。但是,当运行第二次测试时,它会立即通过。我不验证是否调用了stubbed方法,因为我认为不应该明确验证存根。 这是你罗德尼所说的测试是多余的吗?如果是的话,我会在第一次测试的最开始制作存根吗?
答案 0 :(得分:1)
更多的测试通常比较少,所以两次测试都没问题。一个更好的问题是这两个测试是否是多余的:是否有任何情况或输入组合会导致其中一个测试失败,而另一个测试失败?然后需要两个测试。如果他们总是失败或一起成功,那么你可能只需要其中一个。
您何时需要channelName
的不同值?听起来这是一个与这些特定测试无关的配置设置。没关系,也许你会在集成测试中测试更高级别的配置。我会更关心的是为什么它首先是硬编码的:它应该被注入你的类(可能通过构造函数)。然后你可以测试不同的频道名称 - 或不。无论哪种方式,你不想要改变你的代码只是为了测试它是否意味着在你完成后改回它。
答案 1 :(得分:1)
基本上同样Rodney的多重测试问题。根据您的更新,我建议一两件事。
首先,您为两个测试使用了相同的数据。在关于TDD的Kent Beck书中,他提到了“三角测量”的使用。如果您在第二种情况下使用了不同的参考数据,那么您的代码就不会在没有任何额外工作的情况下通过。
另一方面,他还提到删除所有重复,并且重复包括代码和测试之间的重复。在这种情况下,您可以按原样保留两个测试,并重新编译代码中的字符串"channel"
与测试中的字符串之间的重复,方法是将您测试的类中的文字替换为对您的调用communicationRegistry.getChannel()
。在重构之后,您现在只在一个地方使用字符串文字:测试。
两种不同的方法,相同的结果。您使用哪一个归结为个人偏好。在这种情况下,我会采取第二种方法,但那只是我。
提醒看看Rodney对多重测试问题的回答。我猜你可以删除第一个。
谢谢!
布兰登