1

asp.net mvc 4 フレームワークでの単体テストから始めています。

基本的な crud メソッドと save メソッドを含むリポジトリを取得しました。単体テストを作成するときは、テスト リポジトリを作成し、たとえばアイテムがコレクションに追加されるかどうかをテストします。それはすべてスムーズに進みますが、save メソッドがヒットしたかどうかをテストできません。

.save() がヒットした場合に true に設定されるブール型プロパティをテスト リポジトリに追加しようとしました。しかし、インターフェイスとデータベース リポジトリを変更する必要があります。私の意見では、これは実用的でもベストプラクティスでもありません。

これをテストする最良の方法は何ですか? ご回答ありがとうございます。

私のコード:

偽のリポジトリ:

public class TestUserRepository : IUserManagementRepository
    {
        /// <summary>
        /// entries used used for testing
        /// </summary>
        private List<User> _entities;

        /// <summary>
        /// constructor
        /// </summary>
        public TestUserRepository()
        {
            _entities = new List<User>();
            _entities.Add(new User
            {
                Id = 1,
                InsertDate = DateTime.Now,
                LastUpdate = DateTime.Now,
                Username = "TestUserName",
                Password = "TestPassword"
            });
        }
...

public void Create(User task)
        {
            _entities.Add(task);
        }

public void Save()
        {
            //do nothing
        }
    }

テストするコントローラー:

[HttpPost]
        public ActionResult Create(User user)
        {
            if (ModelState.IsValid)
            {
                _repository.Create(user);
                _repository.Save();
                return RedirectToAction("Index");
            }
            else
            {
                return View(user);
            }

        }

そしてテスト

[TestMethod()]
        public void CreateTest()
        {
            IUserManagementRepository repository = new TestUserRepository();
            UserController controller = new UserController(repository);
            User user = new User { Username = "UnitTestUserName", InsertDate = DateTime.Now, LastUpdate = DateTime.Now, Password = "Password" };
            ActionResult actionResult = controller.Create(user);
        User returnedUser = repository.FindBy(u => u.Username == "UnitTestUserName").First<User>();

            Assert.IsNotNull(actionResult);
            Assert.AreEqual(user, returnedUser);            
        }
4

1 に答える 1

1

テスト リポジトリをテストするだけの一連の単体テストを作成しないように注意する必要があります。

次のシナリオを検討してください。

  1. リポジトリにアイテムを追加することになっているサービスメソッドがあります。
  2. 単体テストはこのメソッドを呼び出します。リポジトリで適切な「AddX」メソッドが呼び出されたことを確認する必要があります。

これは有効な単体テスト シナリオです。テストするには、テスト リポジトリを使用できます。これはテスト オブジェクトであるため、完全に制御できます。「AddXMethodCallCount」などのプロパティを公開できます。

時間が経つにつれて、ほとんどボイラープレートである多くのテスト コードを記述していることに気付くでしょう。私が強くお勧めする別の方法は、モック フレームワークを使用することです。

https://stackoverflow.com/questions/37359/what-c​​-sharp-mocking-framework-to-use

慣れるまで少し時間がかかりますが、慣れると、単体テストが大幅に高速化されます。

まだモックを使用したくないが、Save() が呼び出されているかどうかを確認するという目標を達成したい場合は、公開されている SaveMethodCallCount プロパティを追加することをお勧めします。

public class TestUserRepository : IUserManagementRepository
{

...


public SaveMethodCallCount {get; set;}

...
public void Save()
    {
        SaveMethodCallCount++;
    }
}

単体テストでは実際に次のように言うことができるため、これは機能します。

TestUserRepository リポジトリ = 新しい TestUserRepository();

渡されたパラメーターが IUserManagementRepository インターフェイスを実装している限り、UserController は気にしません。コントローラーはインターフェイスを介してリポジトリ オブジェクトと対話しますが、単体テストはその必要はなく、テスト クラスである TestUserRepository には、インターフェイスを介して公開する必要のない、より多くの機能を持たせることができます。

したがって、テストは次のようになります。

[TestMethod()]
    public void CreateTest()
    {
        TestUserRepository repository = new TestUserRepository();
        UserController controller = new UserController(repository);
        User user = new User { Username = "UnitTestUserName", InsertDate = DateTime.Now, LastUpdate = DateTime.Now, Password = "Password" };
        ActionResult actionResult = controller.Create(user);
    User returnedUser = repository.FindBy(u => u.Username == "UnitTestUserName").First<User>();

        Assert.IsNotNull(actionResult);
        Assert.AreEqual(user, returnedUser);  
        Assert.AreEqual(1, repository.SaveMethodCallCount);
    }

私の例を完成させるために、Moq のようなモッキング フレームワークを使用した場合に、これがどのようになるかをお見せしましょう。ここでさらにいくつかの例を見ることができます。テスト メソッドの例では、Moq とArrange/Act/Assertを使用し、Create() が呼び出されたときに Save() が呼び出されるという 1 つのことだけをテストします。

[TestMethod()]
public void Test_SaveCalledWhenCreateCalled()
{    
    // Arrange
    // First, instead of creating an instance of your test class, you create a mock repository. 
    // In fact, you don't need to write any code, the mocking framework handles it. 
    var mockRepository = new Mock<IUserManagementRepository>();
    // and pass the mock repository (which implements the IUserManagementRepository) to your controller
    UserController controller = new UserController(mockRepository);

    // Act
    ActionResult actionResult = controller.Create(user);

    // Assert
    // see how easy it is to do with a mocking framework:
    mockRepository.Verify(rep => rep.Save(), Times.AtLeastOnce());
}
于 2012-08-10T16:14:07.970 に答える