私は複数のレイヤーを持つアプリケーションに取り組んでいます。データソースからデータを取得して保存するデータアクセスレイヤー、データを操作するビジネスロジック、画面にデータを表示するユーザーインターフェイス。
ビジネスロジックレイヤーの単体テストも行っています。唯一の要件は、ビジネスレイヤロジックのフローをテストすることです。そこで、Moqフレームワークを使用してデータアクセスレイヤーをモックし、MS Unitでビジネスロジックレイヤーを単体テストします。
インターフェイスプログラミングを使用して、ユニットテストを実行できるように、設計を可能な限り分離します。インターフェイスを介したビジネスレイヤコールデータアクセスレイヤ。
ビジネスロジックメソッドの1つをテストしようとすると、問題に直面しています。このメソッドはいくつかの作業を行い、オブジェクトを作成してデータアクセスレイヤーに渡します。そのデータアクセスレイヤーメソッドをモックしようとすると、正常にモックできません。
ここでは、問題を示すデモコードを作成しようとしています。
モデル:
public class Employee
{
public string Name { get; set; }
}
データアクセス層:
public interface IDal
{
string GetMessage(Employee emp);
}
public class Dal : IDal
{
public string GetMessage(Employee emp)
{
// Doing some data source access work...
return string.Format("Hello {0}", emp.Name);
}
}
ビジネスロジックレイヤー:
public interface IBll
{
string GetMessage();
}
public class Bll : IBll
{
private readonly IDal _dal;
public Bll(IDal dal)
{
_dal = dal;
}
public string GetMessage()
{
// Object creating inside business logic method.
Employee emp = new Employee();
string msg = _dal.GetMessage(emp);
return msg;
}
}
単体テスト:
[TestMethod]
public void Is_GetMessage_Return_Proper_Result()
{
// Arrange.
Employee emp = new Employee; // New object.
Mock<IDal> mockDal = new Mock<IDal>();
mockDal.Setup(d => d.GetMessage(emp)).Returns("Hello " + emp.Name);
IBll bll = new Bll(mockDal.Object);
// Act.
// This will create another employee object inside the
// business logic method, which is different from the
// object which I have sent at the time of mocking.
string msg = bll.GetMessage();
// Assert.
Assert.AreEqual("Hello arnab", msg);
}
モック作成時の単体テストケースでは、Employeeオブジェクトを送信していますが、ビジネスロジックメソッドを呼び出すと、メソッド内に別のEmployeeオブジェクトが作成されます。それがオブジェクトをモックできない理由です。
その場合、問題を解決できるように設計する方法は?