I have Added Unit Testing in Existing MVC project and also added references
我在现有MVC项目中添加了单元测试,并添加了参考
when i create object of controller
当我创建控制器的对象
it throws an Exception due to DBContext context object i created in MVC but I need to do Dependency Injection and mocking so that it will not check for it.
由于我在MVC中创建的DBContext上下文对象,它会抛出异常,但我需要执行依赖注入和模拟,以便它不会检查它。
please how can i make interface of db to do dependency injection.
请问如何让db的接口做依赖注入。
code in mvc
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);
}
}
where as in test project i only created object of testcontroller
在测试项目中我只创建了testcontroller的对象
2 个解决方案
#1
1
It seems like you didn't mock data access component your controller depends on, right? If this is the case and you are using actual implementation in your unit test, most likely your connection string defined in Test
project is missing or differs from the connection string defined in MVC
project.
看起来你没有模拟控制器所依赖的数据访问组件,对吧?如果是这种情况并且您在单元测试中使用实际实现,则很可能您在Test项目中定义的连接字符串缺失或与MVC项目中定义的连接字符串不同。
Also keep in mind that if you do not mock your controller's dependencies, your unit test is technically cannot be considered as "unit" — it's more like an integration or scenario test.
还要记住,如果你不模仿控制器的依赖关系,你的单元测试在技术上不能被视为“单元” - 它更像是集成或场景测试。
#2
1
You should either abstract the ApplicationDbContext using an interface like IAppDbContext or provide the connection string to the testing project too. In the latter case your test will stop being unit test though.
您应该使用类似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
}
....
}
And now you will be able to inject mock implementations of IAppDbContext in your unit tests.
现在,您将能够在单元测试中注入IAppDbContext的模拟实现。
You should do some research on Dependency Inversion and Mocking.
你应该对依赖倒置和模拟做一些研究。
#1
1
It seems like you didn't mock data access component your controller depends on, right? If this is the case and you are using actual implementation in your unit test, most likely your connection string defined in Test
project is missing or differs from the connection string defined in MVC
project.
看起来你没有模拟控制器所依赖的数据访问组件,对吧?如果是这种情况并且您在单元测试中使用实际实现,则很可能您在Test项目中定义的连接字符串缺失或与MVC项目中定义的连接字符串不同。
Also keep in mind that if you do not mock your controller's dependencies, your unit test is technically cannot be considered as "unit" — it's more like an integration or scenario test.
还要记住,如果你不模仿控制器的依赖关系,你的单元测试在技术上不能被视为“单元” - 它更像是集成或场景测试。
#2
1
You should either abstract the ApplicationDbContext using an interface like IAppDbContext or provide the connection string to the testing project too. In the latter case your test will stop being unit test though.
您应该使用类似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
}
....
}
And now you will be able to inject mock implementations of IAppDbContext in your unit tests.
现在,您将能够在单元测试中注入IAppDbContext的模拟实现。
You should do some research on Dependency Inversion and Mocking.
你应该对依赖倒置和模拟做一些研究。