如何在mvc项目中插入依赖注入

时间:2015-02-05 12:18:34

标签: asp.net-mvc asp.net-mvc-4 unit-testing model-view-controller

我已在现有MVC项目中添加了单元测试,并添加了参考

当我创建控制器的对象

由于在MVC中创建的DBContext上下文对象,它会引发异常,但我需要执行依赖注入和模拟,以便它不会检查它。

请问如何让db的接口进行依赖注入。

mvc中的代码

public class TestingController : Controller
    {
        //
        // GET: /Testing/

        ApplicationDbContext db = new ApplicationDbContext();

        Random rnd = new Random();
        [Authorize]
        public ActionResult Index()
        {
            string uName = User.Identity.GetUserName();
            QuestionsViewModel vm = new QuestionsViewModel();
            List<AddQuestion> adlist = new List<AddQuestion>();
            List<QuestionsViewModel> qlist = new List<QuestionsViewModel>();
            List<int> rn = new List<int>();
            List<int> rn2 = new List<int>();
            List<int> rn3 = new List<int>();
            AddQuestion adq = new AddQuestion();
            var Sessionid = System.Guid.NewGuid();
            vm.sessionid = Sessionid.ToString();
            Session["ApplicantSession"] = Sessionid.ToString();

            ViewBag.StartTime = Session.Timeout;


            List<List<int>> threecompQids = new List<List<int>>();
            List<int> c1question = db.AddQuestions.Where(x => x.ComplexityLevel == 1)
                .Select(y => y.AddQuestionID).ToList();
            List<int> c2question = db.AddQuestions.Where(x => x.ComplexityLevel == 2)
                .Select(y => y.AddQuestionID).ToList();
            List<int> c3question = db.AddQuestions.Where(x => x.ComplexityLevel == 3)
              .Select(y => y.AddQuestionID).ToList();
            for (int i = 0; i < 5; i++)
            {
                int r = rnd.Next(c1question.Min(), c1question.Max() + 1);
                while (!(c1question.Any(w => w.Equals(r)) && !rn.Any(w => w == r)))
                {
                    r = rnd.Next(c1question.Min(), c1question.Max() + 1);
                }
                rn.Add(r);
                r = rnd.Next(c2question.Min(), c2question.Max() + 1);
                while (!(c2question.Any(w => w.Equals(r)) && !rn2.Any(w => w == r)))
                {
                    r = rnd.Next(c2question.Min(), c2question.Max() + 1);
                }
                rn2.Add(r);
                r = rnd.Next(c3question.Min(), c3question.Max() + 1);
                while (!(c3question.Any(w => w.Equals(r)) && !rn3.Any(w => w == r)))
                {
                    r = rnd.Next(c3question.Min(), c3question.Max() + 1);
                }
                rn3.Add(r);

            }



            var fstquestion = rn[0];
            threecompQids.Add(rn);
            threecompQids.Add(rn2);
            threecompQids.Add(rn3);

            vm.ComplexLevQidsLists = threecompQids;

            adq = db.AddQuestions.Find(fstquestion);
            List<Option> opt = db.Options.Where(op => op.AddQuestionID == adq.AddQuestionID).ToList();
            vm.Questions = adq;
            vm.Options = opt;
            vm.UserName = uName;

            return View(vm);


        }

}

在测试项目中我只创建了testcontroller的对象

2 个答案:

答案 0 :(得分:1)

您似乎没有模拟控制器所依赖的数据访问组件,对吧?如果是这种情况,并且您在单元测试中使用实际实现,则很可能在Test项目中定义的连接字符串缺失或与MVC项目中定义的连接字符串不同。

另请注意,如果您不模仿控制器的依赖关系,那么您的单元测试在技术上不能被视为&#34; unit&#34; - 它更像是集成或场景测试。

答案 1 :(得分:1)

您应该使用类似IAppDbContext的接口抽象ApplicationDbContext,或者也可以将连接字符串提供给测试项目。在后一种情况下,您的测试将停止进行单元测试。

public class MyController: Controller
{
    IAppDbContext _context;

    pulbic MyController(IAppDbContext context)
    {
        _context = context; // Now you can use the interface to perform your data access operations
    }

    ....
}

现在,您将能够在单元测试中注入IAppDbContext的模拟实现。

你应该对依赖倒置和模拟做一些研究。