Nunit:测试旧版代码(私有无效)方法

时间:2018-08-10 17:54:43

标签: c# unit-testing nunit

我受命为一堆旧代码进行单元测试。以下方法的特定任务/目标是测试是否正在调用messageProcessor.ProcessCustomerPhoneContactInfo(currentPhoneContact)方法。我还发布了我到目前为止编写的测试存根,但是我希望能有所帮助,因为我认为我在这里遇到了麻烦。如何在测试中填写空白?

正在测试的方法:

private void logPhoneCallDialog_SaveContact(Contact currentPhoneContact)
    {           
        if (currentPhoneContact != null)
        {
            RefreshRenewalActivity();

            if (currentPhoneContact.TypeId == ResultType.TookAppointment)
        }

        NotifyServerOfActivity();

        ApplyAppointmentFilters();

        this.Activate();

        var messageProcessor = new MessageProcessor();
        messageProcessor.ProcessCustomerPhoneContactInfo(currentPhoneContact);
    }

测试:

[TestFixture, RequiresSTA]
class BucketBrowserTest
{
    [Test]
    public void logPhoneCallDialog_SaveContact()
    {
        //Arrange            

        //Act

        //Assert
    }
}

调用上述方法的方法

private void ShowPhoneCallLoggerDialog()
    {
        PhoneCallLoggerDialog dialog = new PhoneCallLoggerDialog(CurrentCustomer, CurrentBucket.BucketTypeId);
        dialog.Owner = this;
        dialog.SaveContact += new PhoneCallLoggerDialog.SaveContactHandler(logPhoneCallDialog_SaveContact);

        dialog.ShowDialog();
    }

用于调用方法的事件处理程序

public delegate void SaveContactHandler(PhoneContact currentPhoneContact);
    public event SaveContactHandler SaveContact;

2 个答案:

答案 0 :(得分:1)

根据您提供的其他信息,在描述可能的解决方案之前,我将概述我的假设:

  1. 您可以安全地构造此类的实例,而无需调用任何进程外的东西
  2. 调用logPhoneCallDialog_SaveContact()不会触发阻止其测试的副作用

重构遗留代码时,通常必须做出通常会避免的设计选择。其中可以包括:

  1. 测试实施细节
  2. 设置方法publicinternal
  3. 添加简单方便测试的浅色抽象

为了对此进行测试,您将至少要做其中一项。

首先,使logPhoneCallDialog_SaveContact public

public void logPhoneCallDialog_SaveContact(Contact currentPhoneContact)
{
    // same body as before
}

接下来,提取一个方法来保存第一个方法的整个主体,以结束此操作:

public void logPhoneCallDialog_SaveContact(Contact currentPhoneContact)
{
    SaveContact(currentPhoneContact);
}

private void SaveContact(Contact currentPhoneContact)
{
    if (currentPhoneContact != null)
    {
        RefreshRenewalActivity();

        // This code from your example doesn't compile.
        if (currentPhoneContact.TypeId == ResultType.TookAppointment)
    }

    NotifyServerOfActivity();

    ApplyAppointmentFilters();

    this.Activate();

    var messageProcessor = new MessageProcessor();
    messageProcessor.ProcessCustomerPhoneContactInfo(currentPhoneContact);
}

采用新方法public

public void SaveContact(Contact currentPhoneContact)
{
    // same body as before
}

如果尚未提取MessageProcessor的接口:

public interface IMessageProcessor
{
    ProcessCustomerPhoneContactInfo(Contact currentPhoneContact);
}

public class MessageProcessor : IMessageProcessor
{
    public void ProcessCustomerPhoneContactInfo(Contact currentPhoneContact)
    {
        // implementation
    }
}

现在像这样修改方法:

public void logPhoneCallDialog_SaveContact(Contact currentPhoneContact)
{
    var messageProcessor = new MessageProcessor();
    SaveContact(currentPhoneContact, messageProcessor);
}

public void SaveContact(
    Contact currentPhoneContact,
    IMessageProcessor messageProcessor)
{
    if (currentPhoneContact != null)
    {
        RefreshRenewalActivity();

        if (currentPhoneContact.TypeId == ResultType.TookAppointment)
    }

    NotifyServerOfActivity();

    ApplyAppointmentFilters();

    this.Activate();

    messageProcessor.ProcessCustomerPhoneContactInfo(currentPhoneContact);
}

现在针对SaveContact编写单元测试,模拟IMessageProcessor,而不是针对logPhoneCallDialog_SaveContact

编辑

这里是一个示例,按要求。自从我使用Moq到现在已经有一段时间了-这是您的原始问题-因此语法可能不太正确,但是像这样:

[Test]
public void SavesContact()
{
    // Arrange
    var contact = new Contact();
    var messageProcessor = new Mock<IMessageProcessor>();

    var subject = // whatever class contains the logPhoneCallDialog_SaveContact method          

    // Act
    subject.SaveContact(contact, messageProcessor.Object);

    // Assert
    messageProcessor.Verify(x => x.ProcessCustomerPhoneContactInfo(contact), Times.Once());
}

还要测试contactnull的情况。

答案 1 :(得分:0)

使用现有的代码,您无法模拟$(document).ready(function(){ }); ,但进行一些更改后,您可以:

messageProcessor

然后,您可以Moq / Mock接口,并确定是否调用了该函数。