依存性注入にNinjectを使用するかなり標準的な.NET MVC 3アプリケーションがあります。私が単体テストしようとしているのは、コントローラから返されるビューです。そこにグループサービスを持つコントローラがあり、サービスはリポジトリを持っています。サービスはまず、そのグループが存在するかどうかを調べ、グループが存在する場合は、エラーと共にfalseを返します。次に、ブール値をチェックして、ユーザーをグループのリストに移動するか、現在のページに留まり、値を表示するかを決定します。依存性注入サービスとリポジトリを持つユニットテストコントローラ
コントローラ
[HttpPost]
public ActionResult AddGroup(Group g)
{
string error = string.Empty;
if (groupService.Save(g, CurrentUser, out error))
{
return RedirectToAction("GetGroups");
}
else
{
ViewData["Error"] = error;
return View("AddGroup");
}
}
私は、TEにしようとしているどのようなサービス
[Inject]
public IGroupRepository CurrentGroupRepo { get; set; }
public bool Save(Group group, string username, out string error)
{
error = string.Empty;
var found = CurrentGroupRepo.GetGroup(group.Descr, false);
if (found != null)
{
error = "That group alread exists";
return false;
}
if (group.CreatedBy == null || group.CreatedBy == string.Empty)
{
group.CreatedBy = username;
group.CreatedOn = DateTime.Now;
group.IsDeleted =false;
}
group.ModifiedBy = username;
group.ModifiedOn = DateTime.Now;
try
{
if (group.GroupID == 0)
{
CurrentGroupRepo.AddGroup(group);
}
else
{
CurrentGroupRepo.UpdateGroup(group);
}
return true;
}
catch (Exception ex)
{
error = ex.Message + ex.StackTrace;
return false;
}
}
ユニットテスト
[TestMethod]
public void TestAddGroup()
{
// Arrange
Mock<IUserService> uService = new Mock<IUserService>();
Mock<IGroupService> gService = new Mock<IGroupService>();
Mock<IObservationService> oService = new Mock<IObservationService>();
Mock<IGroupRepository> mockGroupRepo = new Mock<IGroupRepository>();
string error = string.Empty;
List<Group> groups = new List<Group>();
Group newGroup = new Group() { Descr = "Test Group 1234566", IsDeleted = false };
Mock<IGroupRepository> mockGroupRepo = new Mock<IGroupRepository>();
mockGroupRepo.Setup(cr => cr.GetGroups(It.IsAny<bool>())).Returns(
delegate {
return groups;
});
mockGroupRepo.Setup(cr => cr.GetGroup(It.IsAny<string>(), It.IsAny<bool>())).Returns(
delegate(Group _group) {
return groups.Where(f => f.Descr == _group.Descr).FirstOrDefault();
});
mockGroupRepo.Setup(cr => cr.AddGroup(newGroup)).Returns(
delegate {
groups.Add(newGroup);
return newGroup;
});
gService.SetupGet(d => d.CurrentGroupRepo).Returns(mockGroupRepo.Object);
AdminController controller = new AdminController(gService.Object, uService.Object, oService.Object);
Group newGroup = new Group() { Descr = "Test Group 1234566", IsDeleted = false };
var success = (ViewResult)controller.AddGroup(newGroup);
Assert.IsTrue("GetGroups" == success.ViewName);
var failure = (ViewResult)controller.AddGroup(newGroup);
Assert.IsTrue("AddGroup" == failure.ViewName);
}
私が1つのグループを追加すると、そのグループが機能するはずです。同じグループを追加すると、別のグループに移動する必要があります。しかし、今は単体テストは嘲笑されたものの代わりに実際のリポジトリを使用しています。実際のリポジトリを実際に使用するのではなく、ユニットテストによって制御されるように、模擬サービス上のリポジトリを取得するにはどうすればよいですか?
単体テスト内のコレクションではなくデータベースに保存し続けるため、非常に簡単なことがあります。私は手動でリポジトリを設定してモックサービスに配置することを示すためにテストを更新しましたが、デリゲートは決して呼び出されません。 NinjectModuleを使用して単体テスト用のモックに新しいバインディングを作成するDefaultModuleを作成する必要がありますか? – Josh
@Josh私はninjectの専門家ではありません。私はウィンザーを使用しますが、コンセプトは同じでなければなりません。私が見ることで、コントローラがリポジトリを使用しないので、リポジトリをモックアウトする必要はありません。実際、あなたのIoCは単体テストレベルでは関連してはいけません。あなたは単体テストワイヤーからすべてを見せていますか?あなたが見せていない設定はありますか? – Bronumski
あなたの答えは正しい方向に向いていました。私はフォローアップを投稿します。 – Josh