我有一个基本上是管道的类。它处理消息,然后批量删除它们。为此,ProcessMessage()
方法不直接删除消息;它将它们添加到私人Observable<IMessage>()
。然后我有另一个公共方法,它监视可观察的并且整体删除消息。
这导致代码类似于:
public void CreateDeletionObservable(int interval = 30, int messageCount = 10)
{
this.processedMessages.Buffer(TimeSpan.FromSeconds(interval), messageCount).Subscribe(observer =>
{
client.Value.DeleteMessages(observer.ToList());
});
}
问题是我的单元测试没有processedMessages
的值。我不能提供moq'd值,因为它是私有的。我不需要测试processedMessages中的值;我只需要它们存在就可以测试该方法的行为。具体来说,我需要测试我的observable是否会在抛出异常时继续运行(该逻辑不在代码中)。在我看来,我有几个选择:
1)重构我的类以使用单个怪物可观察链,其具有单个入口点和几个出口(成功,错误,重试等)。此将避免使用私有属性在公共方法之间传递集合。但是,这个链很难解析更少的单元测试。我不相信让我的代码不那么可读和可测试是一个可行的选择。
2)修改我的CreateDeletionObservable
方法以接受消息的测试列表:
public void CreateDeletionObservable(int interval = 30, int messageCount = 10, IObservable<IMessage> processedMessages = null)
这将允许我为使用的方法提供存根数据,但这是一种可怕的代码味道。对此的一个变化是在构造函数级别注入Observable,但这并不是更好。可能更糟。
3)公开processedMessages
。
4)不要测试此功能。
我不喜欢这些选项,但我倾向于2;为测试目的注入列表。我在这里找不到一个选项吗?
答案 0 :(得分:1)
你的感官很好。我想在这种情况下你可以回到我发现有用的指导&#34;测试你的界限&#34; (Udi Dahan,但无法找到参考)。
您似乎可以输入消息(通过Observable Sequence),并且作为副作用,您最终将从客户端删除这些消息。因此,您的测试似乎应该读取类似
的内容所以不要测试管道的这个小部分,而是以某种方式知道this.processedMessages
(该实例来自哪里?),测试链。但这并不意味着您需要创建一个庞大的无法使用的链。只需创建足够的链以使其可测试。
提供更多代码库也会有所帮助,例如: this.processedMessages
&amp; client.Value
来自哪里?这可能是关键,并且猜测应用更实用的方法可能会有所帮助吗?