如何在NUnit 2.6.2中跨测试用例传递值

  • 本文关键字:测试用例 NUnit nunit
  • 更新时间 :
  • 英文 :


在单元测试案例中,我有两个方法,第一个将记录插入数据库,第二个检索回数据。我希望检索数据的输入参数应该是第一个方法中生成的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);
}

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

请告诉我是否有办法在测试用例中共享参数。

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

  • 应使用新鲜夹具进行单元测试
  • 防图案共享固定装置

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

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

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

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

示例

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

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

最新更新