1

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

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

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

请让我知道是否有办法在测试用例之间共享参数。

4

1 回答 1

5

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

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

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

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

  • 使用模拟对象与数据库解耦
  • InsertInfo应该插入信息并使用模拟验证是否执行了带有参数的适当插入调用
  • GetInfo应该使用返回假的模拟record并验证它是否正常工作

例子

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

// 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:这里有完整的例子

于 2012-12-13T10:12:41.500 回答