【问题标题】:Seeding repository Rhino Mocks播种库 Rhino Mocks
【发布时间】:2010-06-17 20:31:08
【问题描述】:

我正在开始我的第一次 C# 测试驱动开发之旅。首先,我使用 MSTest 和 Rhino.Mocks。我正在尝试针对我的ICustomerRepository 编写我的第一个单元测试。为每种测试方法新建一个Customer 似乎很乏味。在 ruby​​-on-rails 中,我会创建一个种子文件并为每个测试加载客户。我可以将这个样板 Customer 放入测试类的属性中似乎是合乎逻辑的,但是我会冒着被修改的风险。我有哪些简化此代码的选择?

[TestMethod]
public class CustomerTests : TestClassBase
{
    [TestMethod]
    public void CanGetCustomerById()
    {
        // arrange
        var customer = new Customer()
        {
            CustId = 5,
            DifId = "55",
            CustLookupName = "The Dude",
            LoginList = new[] {
                new Login { LoginCustId = 5, LoginName = "tdude" } }
        };

        var repository = Stub<ICustomerRepository>();

        // act
        repository.Stub(rep => rep.GetById(5)).Return(customer);

        // assert
        Assert.AreEqual(customer, repository.GetById(5));
    }

    [TestMethod]
    public void CanGetCustomerByDifId()
    {
        // arrange
        var customer = new Customer()
        {
            CustId = 5,
            DifId = "55",
            CustLookupName = "The Dude",
            LoginList = new[] {
                new Login { LoginCustId = 5, LoginName = "tdude" } }
        };

        var repository = Stub<ICustomerRepository>();

        // act
        repository.Stub(rep => rep.GetCustomerByDifID("55")).Return(customer);

        // assert
        Assert.AreEqual(customer, repository.GetCustomerByDifID("55"));
    }

    [TestMethod]
    public void CanGetCustomerByLogin()
    {
        // arrange
        var customer = new Customer()
        {
            CustId = 5,
            DifId = "55",
            CustLookupName = "The Dude",
            LoginList = new[] {
                new Login { LoginCustId = 5, LoginName = "tdude" } }
        };

        var repository = Stub<ICustomerRepository>();

        // act
        repository.Stub(rep =>
            rep.GetCustomerByLogin("tdude")).Return(customer);

        // assert
        Assert.AreEqual(customer, repository.GetCustomerByLogin("tdude"));
    }
}

测试基类

public class TestClassBase
{
    protected T Stub<T>() where T : class
    {
        return MockRepository.GenerateStub<T>();
    }
}

ICustomerRepository 和 IRepository

public interface ICustomerRepository : IRepository<Customer>
{
    IList<Customer> FindCustomers(string q);
    Customer GetCustomerByDifID(string difId);
    Customer GetCustomerByLogin(string loginName);
}

public interface IRepository<T>
{
    void Save(T entity);
    void Save(List<T> entity);
    bool Save(T entity, out string message);
    void Delete(T entity);
    T GetById(int id);
    ICollection<T> FindAll();
}

【问题讨论】:

    标签: c# unit-testing tdd rhino-mocks mstest


    【解决方案1】:

    您的单元测试没有任何实际价值,因为它们只是在测试 Rhino.Mocks。

    您要做的是使用 Rhino.Mocks 为需要 ICustomerRepository 的其他组件/服务创建 ICustomerRepository 存根。这样,您将使用存根的 ICustomerRepository 而不是使用与数据库或某些平面文件对话的 CustomerRepository,Rhino.Mocks 将允许您设置对某些方法的预定义响应,从而允许您在隔离。

    【讨论】:

      【解决方案2】:

      我会将创建客户的代码提取到一个方法中。你可以从你的测试方法中调用它,如果你把它命名为SetUpCustomerForRepository,那么它会提供一些关于你在做什么的文档。

      这是一个基于您的示例的示例:

       private Customer SetUpCustomerForRepository()
       {
          return new Customer()
          {
              CustId = 5,
              DifId = "55",
              CustLookupName = "The Dude",
              LoginList = new[] {
                  new Login { LoginCustId = 5, LoginName = "tdude" } }
          };
       }
      

      您也可以从测试设置方法中调用它,但我实际上更喜欢在测试方法中调用它,以便查看测试的人知道正在为测试设置什么。

      至于你担心它被修改......如果发生这种情况,那么你的测试将失败,你会知道的。

      【讨论】:

      • 我想我知道你在说什么,但你介意为了后代把它写成代码吗? :)
      • 添加了创建客户的方法,然后注意到您的测试在 Rhino Mocks 中为存根使用了不同的条件,因此最好将它们留在测试中(这样更容易看到你正在测试什么)。
      【解决方案3】:

      您可以通过修改存根和断言以使用其属性来免疫测试客户的更改:

      [TestMethod]
      public void CanGetCustomerByDifId() {
      
          var customer = this.TestCustomer;
      
          var repository = Stub<ICustomerRepository>();
      
          repository.Stub(rep => rep.GetCustomerByDifID(customer.DifID))
                    .Return(customer);
      
          Assert.AreEqual(customer, repository.GetCustomerByDifID(customer.DifID));
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-03-21
        • 2011-04-25
        • 2011-04-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-12
        • 2010-10-03
        相关资源
        最近更新 更多