代码之家  ›  专栏  ›  技术社区  ›  czuroski

我应该在下面的例子中使用mocking吗

  •  5
  • czuroski  · 技术社区  · 14 年前

    [TestMethod()]
            public void NextSaturdayTest()
            {
                DateTime date = new DateTime(); 
                date = DateTime.Parse("2010-08-14");
                DateTime expected = new DateTime(); 
                expected = DateTime.Parse("2010-08-21");
                DateTime actual;
                actual = DateExtensions.NextSaturday(date);
                Assert.AreEqual(expected, actual);
    
                date = DateTime.Parse("2010-08-19");
                expected = DateTime.Parse("2010-08-21");
                actual = DateExtensions.NextSaturday(date);
                Assert.AreEqual(expected, actual);
            }
    

    首先,这代表了良好的测试实践吗? 第二,使用模拟框架来创建这个测试有什么好处?

    如果我能提供更多的信息,请告诉我。

    谢谢你的任何想法

    4 回复  |  直到 14 年前
        1
  •  7
  •   Carl Manaster    14 年前

    首先,不要这样做:

    DateTime date = new DateTime();
    date = DateTime.Parse("2010-08-14");
    

    您正在创建一个新的datetime,然后在解析字符串以获取新的datetime时将其丢弃日期时间。记得吗,测试代码应该还是好代码。

    ReturnsCorrectNextSaturdayGivenAWednesday , ReturnsCorrectNextSaturdayWhenCrossesEndOfMonth ,和 ReturnsCorrectNextSaturdayWhenCrossesEndOfYear

    最后,没有理由在这里嘲笑。如果您的DateExtensions调用了另一个组件(比如说数据库),并且您想伪造该调用,那么mock是合适的。因此,与测试DateExtensions+数据访问不同,您只需测试DateExtensions,当它调用数据访问层时,您的测试将建立一个模拟。

        2
  •  5
  •   Carl Manaster    14 年前

    模拟用于满足依赖关系。

    例如。考虑是否有一个类使用IDataLayer(围绕数据库的包装器)从数据库加载用户

    public class UserService
    {
        public UserService(IDataLayer layer) {}
        public User GetById(int id)
    } 
    

    测试时,您不希望针对数据库进行测试。这使得提供数据和检查结果变得困难。相反,您可以模拟IDataLayer对象,以便能够手动向UserService提供用户。这使得验证用户服务是否做了它应该做的事情变得更加容易。

    至于你的测试方法。我将把它分成两个方法,因为您正在运行两个不同的测试(尽管是在同一个方法上)

        3
  •  2
  •   Grzenio    14 年前

    你的测试相当合理。为了更好的可读性,我个人会将大部分日期解析内联:

    [TestMethod()]
        public void NextSaturdayTest()
        {
            DateTime actual = DateExtensions.NextSaturday(DateTime.Parse("2010-08-14"));
            Assert.AreEqual(DateTime.Parse("2010-08-21"), actual);
    
            actual = DateExtensions.NextSaturday(DateTime.Parse("2010-08-19"));
            Assert.AreEqual(DateTime.Parse("2010-08-21"), actual);
        }
    
        4
  •  2
  •   Adam Lear    14 年前

    我觉得你在这种情况下不用嘲笑就可以了。通常,您会模拟某种依赖关系(例如,如果您有 DateProvider 但在这种情况下,使用 DateTime 我觉得很好。

    不过,我还是会帮你整理一下试卷的。您应该坚持对每个方法测试一件事,因为如果该测试方法失败,您将知道它失败的原因,而不必检查断言并怀疑其余的断言是否会通过。

    [TestMethod()]
    public void NextSaturdayReturnsCorrectValueStartingFromASaturday()
    {
        DateTime date = DateTime.Parse("2010-08-14");
    
        DateTime expected = DateTime.Parse("2010-08-21");
        DateTime actual = DateExtensions.NextSaturday(date);
    
        Assert.AreEqual(expected, actual);
    }
    
    [TestMethod()]
    public void NextSaturdayReturnsCorrectValueWithinTheSameWeek() 
    {
        DateTime date = DateTime.Parse("2010-08-19");
        DateTime expected = DateTime.Parse("2010-08-21");
        DateTime actual = DateExtensions.NextSaturday(date);
    
        Assert.AreEqual(expected, actual);
    }