播种存储库 Rhino Mocks

发布于 2024-09-05 18:31:35 字数 2909 浏览 1 评论 0原文

我即将开始我的第一次 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();
}

I am embarking upon my first journey of test driven development in C#. To get started I'm using MSTest and Rhino.Mocks. I am attempting to write my first unit tests against my ICustomerRepository. It seems tedious to new up a Customer for each test method. In ruby-on-rails I'd create a seed file and load the customer for each test. It seems logical that I could put this boiler plate Customer into a property of the test class but then I would run the risk of it being modified. What are my options for simplifying this code?

[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"));
    }
}

Test Base Class

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

ICustomerRepository and 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();
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

网白 2024-09-12 18:31:35

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

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

Your unit tests don't have any real value because they're just testing Rhino.Mocks.

What you want to do is use Rhino.Mocks to create an ICustomerRepository stub for other components/services that need an ICustomerRepository. This way, instead of using a CustomerRepository that talks to a database or some flat file, you'll use the stubbed ICustomerRepository and Rhino.Mocks will let you set up pre-defined responses to certain methods, thus allowing you to test your services in isolation.

回眸一遍 2024-09-12 18:31:35

我会将创建客户的代码提取到一个方法中。您可以从测试方法中调用它,如果您将其命名为 SetUpCustomerForRepository 之类的名称,那么它将提供一些有关您正在执行的操作的文档。

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

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

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

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

I would extract the code to create the customer into a method. You can call that from your test methods, and if you name it something like SetUpCustomerForRepository then it will provide some documentation about what you are doing.

Here is an example based on your sample:

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

You could also call it from the test set up method, but I actually prefer to do it in the test method so that people looking at the test know what is being set up for the test.

As for your concern about it being modified....if that happens, then your tests will fail, and you'll know about it.

心的憧憬 2024-09-12 18:31:35

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

[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));
}

You could immunize yourself against changes to your test customer by modifying your stubs and assertions to use its properties:

[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));
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文