我是否应该使用模拟以下示例

czu*_*ski 5 c# tdd unit-testing mocking

我对使用TDD相对较新,并且最近一直在阅读有关模拟对象的内容.我有以下测试来测试给定日期返回下一个星期六的方法.

[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);
        }
Run Code Online (Sandbox Code Playgroud)

首先,这是否代表了良好的测试实践?其次,利用模拟框架创建此测试的优势是什么?

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

谢谢你的任何想法

Phi*_*eck 7

首先,不要这样做:

DateTime date = new DateTime();
date = DateTime.Parse("2010-08-14");
Run Code Online (Sandbox Code Playgroud)

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

其次,一个好的测试测试一件事.你可能有多个测试,如ReturnsCorrectNextSaturdayGivenAWednesday,ReturnsCorrectNextSaturdayWhenCrossesEndOfMonthReturnsCorrectNextSaturdayWhenCrossesEndOfYear.

最后,没有理由在这里嘲笑.如果您的DateExtensions调用另一个组件(比如数据库),并且您想伪造该调用,那么模拟将是合适的.因此,不是测试DateExtensions + Data Access,而是仅测试DateExtensions,当它调用数据访问层时,它将是您的测试设置的模拟.


jga*_*fin 5

模拟用于满足依赖性.

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

public class UserService
{
    public UserService(IDataLayer layer) {}
    public User GetById(int id)
} 
Run Code Online (Sandbox Code Playgroud)

测试时,您不希望针对数据库进行测试.这使得提供数据和检查结果变得很困难.相反,您模拟IDataLayer对象以便能够手动向UserService提供用户.它使得验证UserService完成它应该做的事情变得容易得多.

至于你的测试方法.我会把它分解为两种方法,因为你运行了两个不同的测试(虽然在同一个方法上)