2

私は RhinoMocks と一緒に MsTest を使用して TDD を実践しています。また、可能な限り怠惰になろうとしています。つまり、できる限り VS2012 の自動生成を利用しています。しかし、Arrange-Act-Assert 方法論を使用してテスト メソッド全体を作成し、クラスとそのコンストラクターおよびプロパティを設定するだけでよいとは限りません。

現在、テスト クラスでいくつかのプロパティを作成するのが最も簡単であることがわかりました (それらを使用しない場合でも)、コード生成のみを目的としています。私の質問は、これは悪い習慣ですか、それを行うためのより良い/簡単な方法はありますか? 良くも悪くも、コメントは大歓迎です。ありがとうございました!

[TestClass]
public class MainViewModelTest
{
    private MainViewModel MainViewModel
    {
        get
        {
            var facilityDataEntity = MockRepository.GenerateStub<FacilityDataEntity>();

            var viewModel = new MainViewModel(facilityDataEntity)
            {
                FacilityValue = string.Empty,
                FacilityLabel = string.Empty
            };

            return viewModel;
        }
    }

    private MainViewModel MainViewModelWithFacilityAndShopOrderData
    {
        get
        {
            var facilityDataEntity = MockRepository.GenerateStub<FacilityDataEntity>();
            var shopOrderDataEntity = MockRepository.GenerateStub<ShopOrderDataEntity>();

            var viewModel = new MainViewModel(facilityDataEntity, shopOrderDataEntity)
            {
                FacilityValue = string.Empty,
                FacilityLabel = string.Empty,
                ShopOrder = 99999999,
                RequiredQuantity = 0M,
                ItemCode = string.Empty,
                ItemDescription = string.Empty
            };

            return viewModel;
        }
    }

    [TestMethod]
    public void MainViewModel_TranslateDataEntityListMethodReturnsMainViewModelRecords()
    {
        // Arrange
        var facilityDataEntityList = MockRepository.GenerateStub<IEnumerable<FacilityDataEntity>>();
        var shopOrderDataEntityList = MockRepository.GenerateStub<IEnumerable<ShopOrderDataEntity>>();

        // Act
        IEnumerable<MainViewModel> facilityResults = MainViewModel.TranslateDataEntityList(facilityDataEntityList);
        IEnumerable<MainViewModel> shopOrderResults = MainViewModel.TranslateDataEntityList(facilityDataEntityList, shopOrderDataEntityList);

        // Assert
        Assert.IsInstanceOfType(facilityResults, typeof(IEnumerable<MainViewModel>));
        Assert.IsInstanceOfType(shopOrderResults, typeof(IEnumerable<MainViewModel>));
    }
}
4

2 に答える 2

3

テスト クラス内で共通のコードをラップすることは間違いではありませんが、テスト間で状態を共有する可能性は避けたいと思います。

ここで使用できるアプローチは 2 つあります。

クラス/テストの初期化

Peterがコメントで述べているように、このようなことを行う初期化メソッドを含めるのは簡単です。

//Only runs once per test run
[ClassInitialize]
public void InitClass(){

   //Ideally this should be reserved for expensive operations
   // or for setting properties that are static throughout
   // the lifetime of your test.

}

//Runs for every test
[TestInitialize]
public void TestInit(){

   //Here you can setup common stub/mock behavior
   // that will be common for every test, but ensure
   // it is clean for each test run

}

セットアップ/工場出荷時の方法

もう 1 つのオプションは、繰り返されるテスト コードを減らし、テストの意図をより明確にするために使用できる特殊なセットアップまたはファクトリ メソッドを作成することです。

[TestMethod]
public void ShouldFailIfUserNameIsTed(){

   var user = SetupUserScenario("Ted");

   var result = _myUserService.Validate(user);

   Assert.IsFalse(result);
}

private User SetupUserScenario(String username){

   var user = new User();
   user.Name = username;

   //Do a bunch of other necessary setup

   return user;
}

これがすべて理にかなっていることを願っていますが、これに夢中になりすぎないように注意してください. セットアップ メソッドに多くのものを入れすぎると、テストが不明確になります。テストを読んで、コード内の他の多くの場所を調べなくても、何が起こっているのかを理解できるはずです。

于 2013-03-07T15:42:59.317 に答える
1

そのためのClassInitialize機能です。私は、他の何よりも先に、期待され、推奨される手段を選択します。認識しやすく、コードを理解するのに時間がかかりません。

于 2013-03-08T14:53:11.927 に答える