我应该提取私有方法以进行单元测试吗?

时间:2019-02-21 12:49:55

标签: c# unit-testing testing

我有一个以下类,其中要进行单元测试的所有逻辑都在我提取的私有方法内发生,以供两个Handle方法调用以重用。我所坚持的是对此类进行单元测试的正确方法。我想断言基本上有4种可观察的行为:

  1. 注册不存在时不调用“替换”
  2. 文档不存在时不调用“替换”
  3. 文档消息为最新状态时不调用“替换”
  4. 在所有其他条件都成功时调用“替换”

我可以轻松地复制两种公共Handle方法的所有单元测试。但是我想知道将私有方法提取到使用可以直接测试的公共方法暴露这种行为的类中是否更合适。

有想法吗?

public class Denormalizer :
    INotificationHandler<LightsMessageReceived>,
    INotificationHandler<AnnouncementsMessageReceived>
{
    public Task Handle(AnnouncementsMessageReceived notification, CancellationToken cancellationToken)
    {
        return HandleMessage(notification, document => document.Announcements, cancellationToken);
    }

    public Task Handle(LightsMessageReceived notification, CancellationToken cancellationToken)
    {
        return HandleMessage(notification, document => document.Lights, cancellationToken);
    }

    private async Task HandleMessage(InventoryMessage message, Func<SaleRegistration, ISequenced> getMessageId, CancellationToken cancellationToken)
    {
        var registration = await docContext.CsoMessage.GetSaleRegistration(message.SiteId, message.InventoryId, cancellationToken);

        if (registration == null) return;

        var document = await docContext.SaleRegistration.Get(message.SiteId, message.InventoryId, 
            registration.Data.SaleDate, registration.Data.SaleType, cancellationToken);

        if (document == null) return;

        if (getMessageId(document).IsCurrent(message.MessageId)) return;

        document.Map(message);

        await docContext.SaleRegistration.Replace(document);
    }
}

1 个答案:

答案 0 :(得分:1)

最干净的方法是将代码移至可以测试的另一个类。但是,类和方法都不必为public。您还可以使用internal访问修饰符对其进行标记,以便仅可以从同一程序集中访问代码。

此外,您明确授予内部成员访问权限的程序集也可以访问该方法。您可以在主装配体上使用InternalsVisibleTo属性,并授予对单元测试装配体的访问权限。这样,您在允许单元测试访问它时不会完全发布该方法。

当然,如果您决定将方法保留在类中并仅将其标记为internal,这也将起作用,因此您不必创建自己的类(尽管这可能更干净)。

相关问题