Testing a MVC Controller fails with NULL reference exception

前端 未结 1 1472
Happy的楠姐
Happy的楠姐 2020-12-22 13:47

Below is the setup that I am trying to test.

The controller:

public ActionResult UpsertStudent(StudentModel studentModel)
{
    try
         


        
相关标签:
1条回答
  • 2020-12-22 14:07

    I am not sure if I have understood you problem correctly, but looking at the code snippets provided, the test will go and hit the database, because the mock object and its expectation is not defined.

    I would have implemented the solution like this -

    I am making some assumptions that your _updateStudentManager object is for the class that is doing the DB interaction for Student. I'll call it say StudentRepository. And to allow you to mock the behavior I would make it Interface driven. So typically my setup would look like this -

    //Interface
    public interface IStudentrepository
    {
        StudentModel GetStudentInfo(int studentId);
    }
    
    //Class implementing IStudentrepository
    public class StudentRepository : IStudentrepository
    {
        public StudentModel GetStudentInfo(int studentId)
        {
            //Implementation goes here
        }
    }
    

    Now in my controller, I would have an instance of IStudentrepository, which can be injected via constructor.

    public class StudentController
    {
        private readonly IStudentrepository updateStudentManager;
        public StudentController(IStudentrepository updateStudentManager)
        {
            this.updateStudentManager = updateStudentManager;
        }
    }
    //Rest of the code for controller....
    

    Now while writing my Test, I will create a mock object of IStudentrepository, define the expectation for the mock object, and inject it when creating the controller object. Something like this.

        [TestMethod]
        public void TestMethod1()
        {
            //--Arrange--
            //Define a mock object for student repository
            var mock = new Mock<IStudentrepository>();
    
            //Define the expectations of the mock object
            mock.Setup(s => s.GetStudentInfo(It.IsAny<int>()))
                .Returns(new StudentModel {/*return the required object */ });
    
            //Instantiate controller and inject the mock object
            StudentController _controller = new StudentController(mock.Object);
    
            //--Act--
            var res = _controller.UpsertStudent(studentModel) as JsonResult;
    
    
            //--Assert--
            if (res != null) Assert.AreEqual("{ result = True }", res.Data.ToString());
    
        }
    

    Now when your test method calls the GetStudentInfo method, instead of hitting the db, it will return the value as set in mock object.

    This is just a high level implementation, and of course you can modify it as per your design. Hope it helps

    0 讨论(0)
提交回复
热议问题