如何在 NUnit 2.6.2 中跨测试用例传递值? [英] How to pass values across test cases in NUnit 2.6.2?

查看:52
本文介绍了如何在 NUnit 2.6.2 中跨测试用例传递值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在单元测试用例中有两个方法,其中第一个将记录插入数据库,第二个检索回数据.我希望检索数据的输入参数应该是第一个方法中生成的 id.

I am having two Methods in Unit Test case where First Insert Records into Database and Second retrieves back data. I want that input parameter for retrieve data should be the id generated into first method.

private int savedrecordid =0;
private object[] SavedRecordId{ get { return new object[] { new object[] { savedrecordid  } }; } }


[Test]
public void InsertInfo()
{
    Info oInfo = new Info();
    oInfo.Desc ="Some Description here !!!";
    savedrecordid  = InsertInfoToDb(oInfo);
}

[Test]
[TestCaseSource("SavedRecordId")]
public void GetInfo(int savedId)
{
    Info oInfo  = GetInfoFromDb(savedId);
}

我知道每个测试用例都是单独执行的,并且是单独的实例,我们不能跨测试方法共享变量.

I know each test case executed separately and separate instance we can't share variables across test methods.

如果有办法在测试用例之间共享参数,请告诉我.

Please let me know if there is way to share parameters across the test cases.

推荐答案

您描述的情况是单元测试的反模式之一:单元测试应该是独立的,不应依赖于它们运行的​​顺序.您可以在 xUnit Patterns 网站上找到更多信息:

The situation you describe is one of unit tests' antipatterns: unit tests should be independent and should not depend on the sequence in which they run. You can find more at the xUnit Patterns web site:

并且您的两个单元测试都没有断言,因此它们无法证明它们是否通过.

And both your unit tests have no asserts, so they can't prove whether they are passing or not.

而且它们依赖于数据库,即外部资源,因此它们不是单元而是集成测试.

Also they are depend on a database, i.e. external resource, and thus they are not unit but integration tests.

所以我的建议是重写它们:

So my advice is to rewrite them:

  • 使用模拟对象与数据库解耦
  • InsertInfo 应插入信息并使用模拟验证是否已执行适当的insert 带参数调用
  • GetInfo 应该使用返回假 record 的模拟操作,并验证它是否正常工作
  • Use mock object to decouple from database
  • InsertInfo should insert info and verify using the mock that an appropriate insert call with arguments has been performed
  • GetInfo should operate with a mock that returns a fake record and verify that it works fine

注意事项:* 我必须把提单和数据库操作分开……* ...并对您的解决方案做出一些假设

Notes: * I have to separate B/L from database operations… * … and make some assumptions about your solution

// Repository incapsulates work with Database
public abstract class Repository<T>
    where T : class
{
    public abstract void Save(T entity);
    public abstract IEnumerable<T> GetAll();
}

// Class under Test
public class SomeRule
{
    private readonly Repository<Info> repository;

    public SomeRule(Repository<Info> repository)
    {
        this.repository = repository;
    }

    public int InsertInfoToDb(Info oInfo)
    {
        repository.Save(oInfo);

        return oInfo.Id;
    }

    public Info GetInfoFromDb(int id)
    {
        return repository.GetAll().Single(info => info.Id == id);
    }
}

// Actual unittests
[Test]
public void SomeRule_InsertInfo_WasInserted() // ex. InsertInfo
{
    // Arrange
    Info oInfo = new Info();
    oInfo.Desc = "Some Description here !!!";

    var repositoryMock = MockRepository.GenerateStrictMock<Repository<Info>>();

    repositoryMock.Expect(m => m.Save(Arg<Info>.Is.NotNull));

    // Act
    var savedrecordid  = new SomeRule(repositoryMock).InsertInfoToDb(oInfo);

    // Assert
    repositoryMock.VerifyAllExpectations();
}

[Test]
public void SomeRule_GetInfo_ReciveCorrectInfo() // ex. GetInfo
{
    // Arrange
    var expectedId = 1;
    var expectedInfo = new Info { Id = expectedId, Desc = "Something" };

    var repositoryMock = MockRepository.GenerateStrictMock<Repository<Info>>();

    repositoryMock.Expect(m => m.GetAll()).Return(new [] { expectedInfo }.AsEnumerable());

    // Act 
    Info receivedInfo  = new SomeRule(repositoryMock).GetInfoFromDb(expectedId);

    // Assert
    repositoryMock.VerifyAllExpectations();

    Assert.That(receivedInfo, Is.Not.Null.And.SameAs(expectedInfo));
}

ps:完整示例可用这里

这篇关于如何在 NUnit 2.6.2 中跨测试用例传递值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆