【问题标题】:Test Method for constructor构造函数测试方法
【发布时间】:2013-04-02 06:30:31
【问题描述】:

使用 TDD 开发事件调度程序并为以下课程编写测试项目。

决定写一个构造函数逻辑的测试方法

public class TechDay
{
    public Session MorningSlot { get; set; }
    public Session EveningSlot { get; set; }

    public TechDay()
    {
        this.MorningSlot = new Slot();
        this.EveningSlot = new Slot();

        this.MorningSlot.Sessions= new List<Session>();
        this.EveningSlot.Sessions= new List<Session>();
        this.ConfigureEventSettings();
    }

    protected virtual void ConfigureEventSettings()
    { 
      CultureInfo provider = CultureInfo.InvariantCulture;
      this.MorningSlot.StartTime = DateTime.ParseExact("9:00 AM", "h:mm tt", provider);
      this.MorningSlot.EndTime = DateTime.ParseExact("12:00 PM", "h:mm tt", provider);
      this.EveningSlot.StartTime = DateTime.ParseExact("1:00 PM", "h:mm tt", provider);
      this.EveningSlot.EndTime = DateTime.ParseExact("5:00 PM", "h:mm tt", provider);
    }
}

测试方法

[TestMethod]
public void CheckMorningSlot()
{
    TechDay techday=new TechDay();
    Assert.IsNotNull(techday.MorningSlot);
}

[TestMethod]
public void CheckEveningSlot()
{
    TechDay techday=new TechDay();
    Assert.IsNotNull(techday.EveningSlot);
}

[TestMethod]
public void CheckEveningSlotSessions()
{
    TechDay techday=new TechDay();
    Assert.IsNotNull(techday.EveningSlot.Sessions);
}

[TestMethod]
public void CheckMorningSlotSessions()
{
    TechDay techday=new TechDay();
    Assert.IsNotNull(techday.MorningSlot.Sessions);
}

我是否需要编写不同的方法来检查构造函数中的不同参数初始化?也不是构造函数调用另一个方法。

为这段代码编写测试方法的最佳方式是什么?

【问题讨论】:

  • 构造函数中的虚拟方法调用不是个好主意。
  • @Tilak,我只是将该方法设置为虚拟方法,因为其他 conf 事件也可以继承 TechDay 并更改开始和结束时间。例如:科技之夜。什么是最好的建议?
  • Billa,如果你能正确地回忆起构造函数内部的基构造函数、派生构造函数和虚方法之间的调用顺序,以及每次调用时将/不会初始化哪些字段,那可能就可以了。
  • @AlexeiLevenkov,我把它改成了private void 并删除了virtual

标签: c# unit-testing tdd test-project


【解决方案1】:

您应该测试代码的功能需求,而不是每一段代码。那么您正在测试的功能是什么?如果要求早上 9 点开始,那么您的测试将类似于:

[TestMethod]
public void Morning_slot_starts_at_nine_am()
{
    var expected = DateTime.ParseExact("9:00 AM", "h:mm tt", CultureInfo.InvariantCulture);
    var techDay = new TechDay();
    var actual = techDay.MorningSlot.StartTime;
    Assert.AreEqual(expected, actual);
}

【讨论】:

  • 看起来不错,我如何使用 Assert 检查下午 3 点到 4 点之间任何时间的特殊事件
  • @Billa,要求如此不精确是不寻常的,时间通常会遵循规则,您将测试该规则产生正确的结果。但如果这确实是您需要做的,那么我希望在测试中看到一些设置布尔值的东西,显示时间是否在下午 3 点到 4 点之间,然后 Assert.IsTrue(isBetweenThreeAndFourPm);
  • +1。注意 - 无需使用 Parse - 直接从小时/分钟构造 DateTime 会更紧凑,并且由于类型检查而不易出错。如果DateTime 值不包含部分本身,请考虑使用TimeSpan 是否看起来更好......
【解决方案2】:

您必须将配置逻辑提取到另一个类。使用接口来模拟(参见Moq)。你会得到简单的测试。

public class TechDay
{
    public Session MorningSlot { get; set; }
    public Session EveningSlot { get; set; }

    public TechDay(IEventConfigurator morningConfigurator, IEventConfigurator eveningConfigurator)
    {
        MorningSlot = new Session();
        morningConfigurator.Configure(MorningSlot);

        EveningSlot = new Session();
        eveningConfigurator.Configure(EveningSlot);
    }
}

public interface IEventConfigurator
{
    void Configure(Session session);
}

public class Session
{
    public static DateTime StartTime { get; set; }
    public static DateTime EndTime { get; set; }
}

public class FromStringEventConfigurator : IEventConfigurator
{
    private readonly string _begin;
    private readonly string _end;

    public FromStringEventConfigurator(string begin, string end)
    {
        _begin = begin;
        _end = end;
    }

    public void Configure(Session session)
    {
        CultureInfo provider = CultureInfo.InvariantCulture;
        Session.StartTime = DateTime.ParseExact(_begin, "h:mm tt", provider);
        Session.EndTime = DateTime.ParseExact(_end, "h:mm tt", provider);
        // ...
    }
}

【讨论】:

    猜你喜欢
    • 2012-12-29
    • 2013-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多