2012-12-13 40 views
1

我有两种方法在单元测试的情况下,首先插入记录到数据库和第二次检索数据。我希望检索数据的输入参数应该是生成第一个方法的id。如何在NUnit 2.6.2中跨测试用例传递值?

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

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

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

+0

有你尝试过'public string myProp {get; set;}'我发现如果我设置了一个Construtor来设置我需要的数据并填充一些为我工作的getter和setter。 – EllisChadwick

+0

是的我曾尝试创建属性没有锻炼:( – user1664857

回答

5

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

而且两者的单元测试没有断言,所以他们不能证明他们是否通过与否。

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

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

  • 使用mock object从数据库中分离
  • InsertInfo应插入信息,并利用模拟验证相应的插入调用与参数已执行
  • GetInfo应该使用模拟操作,返回假的record并验证其正常工作

注: *我到B/L从数据库操作分开...... * ...,并为您解决一些假设

// 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:完整的例子availabel here

+0

谢谢Akim和乔我不确定模式像共享夹具是否支持nUnit 2.6.2是的我要更新与Mock对象的测试用例,并会去为了验证数据库过程和查询是分开的,在典型的情况下,测试用例必须是独立的,在这里我正在寻找应该测试的整个用户故事,如果你可以提供NUnit的链接或引用2.6共享夹具和最佳做法将是非常有用的。再次坦克反应。 – user1664857

+1

_Shared Fixture_是一个antipatter!因此你必须避免实施它:) 查看答案更新 – Akim