How to pass values across test cases in NUnit 2.6.2?

霸气de小男生 提交于 2019-12-24 09:09:11

问题


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.


回答1:


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:

  • Unit test should be implemented using Fresh Fixture
  • Anti pattern Shared Fixture

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:

  • 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

Example

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: full example availabel here



来源:https://stackoverflow.com/questions/13856246/how-to-pass-values-across-test-cases-in-nunit-2-6-2

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!