同じインターフェイスを実装する複数のクラスがあります。コードの重複を最小限に抑えて (DRY)、各クラスがインターフェイスを正しく実装していることを確認するには、どのように単体テストを記述すればよいですか?
IDeleter
私が言いたいことの例として、以下は:Deleter1
との 2 つの実装を含む非常に基本的なライブラリDeleter2
です。どちらも、関連付けられDelete
た を呼び出すことによってメソッドを実装します。Delete
IRepository
using Microsoft.Practices.Unity;
namespace TestMultiple
{
public interface IRepository
{
void Delete(string id);
}
public abstract class Baseclass
{
protected abstract IRepository GenericRepository { get; }
public void Delete(string id)
{
GenericRepository.Delete(id);
}
}
public interface IDeleter
{
void Delete(string id);
}
public interface IRepository1 : IRepository
{
}
public abstract class RepositoryBase
{
public void Delete(string id)
{
}
}
public class Repository1 : RepositoryBase, IRepository1
{
}
public class Deleter1 : Baseclass, IDeleter
{
protected override IRepository GenericRepository { get { return Repository; } }
[Dependency]
public IRepository1 Repository { get; set; }
}
public interface IRepository2 : IRepository
{
}
public class Repository2 : RepositoryBase, IRepository2
{
}
public class Deleter2 : Baseclass, IDeleter
{
protected override IRepository GenericRepository { get { return Repository; } }
[Dependency]
public IRepository2 Repository { get; set; }
}
}
これら 2 つのクラスDeleter1
とについてDeleter2
、以下のスニペットに示すように、対応する 2 つの単体テスト クラスを作成しました。テストは、同じ動作をチェックします。つまりDelete
、基礎となるリポジトリで呼び出されます。のすべての実装に対して同じテストを実装するより良い方法はありIDeleter
ますか? たとえば、TestDelete
、 for 、 などの一般的なテスト メソッドを含む基底クラスを作成する必要がTestDeleter1
ありTestDeleter2
ますか?
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.Practices.Unity;
using Moq;
namespace TestMultiple.Tests
{
[TestClass]
public class TestDeleter1
{
[TestMethod]
public void TestDelete()
{
var mockRepo = new Mock<IRepository1>();
var container = new UnityContainer().RegisterInstance<IRepository1>(mockRepo.Object);
var deleter = container.Resolve<Deleter1>();
deleter.Delete("id");
mockRepo.Verify(r => r.Delete("id"));
}
}
[TestClass]
public class TestDeleter2
{
[TestMethod]
public void TestDelete()
{
var mockRepo = new Mock<IRepository2>();
var container = new UnityContainer().RegisterInstance<IRepository2>(mockRepo.Object);
var deleter = container.Resolve<Deleter2>();
deleter.Delete("id");
mockRepo.Verify(r => r.Delete("id"));
}
}
}
編集: この種の問題を解決するのに役立つユニット テスト フレームワークについて自由に言及してください。ただし、私の好みは NUnit です。