How to test an asp.net mvc controler using Moq and Entity Framework 6

5

My controller:

[Authorize]
    public class DominioController : Controller
    {

        private IDominioDB _db;

        public DominioController(IDominioDB db)
        {
            _db = db;
        }

        // GET: Dominio
        public async Task<ActionResult> Index()
        {

            var userID = User.Identity.GetUserId();
            var d = await _db.Dominios.Where(x => x.idUsu == userID).ToListAsync();

            ViewBag.Username = User.Identity.Name;

            return View(d);
        }
    }

My test method:

[TestMethod]
        public async Task VERIFICA_CONTROLE_DOMINIO()
        {

            var data = new List<DBDominio>()
            {
                new DBDominio() { idUsu = "usuario1" },
                new DBDominio() { idUsu = "usuario2" },new DBDominio() { idUsu = "usuario2" },
                new DBDominio() { idUsu = "usuario3" },new DBDominio() { idUsu = "usuario3" }
            }.AsQueryable();

            var mockSet = new Mock<DbSet<DBDominio>>();


            mockSet.As<IDbAsyncEnumerable<DBDominio>>()
                .Setup(m => m.GetAsyncEnumerator())
                .Returns(new TestDbAsyncEnumerator<DBDominio>(data.GetEnumerator()));

            mockSet.As<IQueryable<DBDominio>>()
                .Setup(m => m.Provider)
                .Returns(new TestDbAsyncQueryProvider<DBDominio>(data.Provider));


            mockSet.As<IQueryable<DBDominio>>().Setup(m => m.Expression).Returns(data.Expression);
            mockSet.As<IQueryable<DBDominio>>().Setup(m => m.ElementType).Returns(data.ElementType);
            mockSet.As<IQueryable<DBDominio>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());

            var repo = new Mock<Interfaces.IDominioDB>();
            repo.Setup(c => c.Dominios).Returns(mockSet.Object);


            var context = new Mock<ControllerContext>();
            var mockIdentity = new Mock<IIdentity>();
            context.SetupGet(x => x.HttpContext.User.Identity).Returns(mockIdentity.Object);
            mockIdentity.Setup(x => x.Name).Returns("usuario1");



            // Arrange
            DominioController controller = new DominioController(repo.Object)
            {
                ControllerContext = context.Object
            };

            // Act
            ViewResult result = (ViewResult)await controller.Index();

            // Assert
            Assert.IsNotNull(result);
            Assert.AreEqual(result.ViewBag.Username , "usuario1");

        }

I want to know how I could check if the var d = await _db.Dominios.Where(x => x.idUsu == userID).ToListAsync(); that is inside the controler returns the right amount of records, is it possible in this way?

I know that I could create a Services layer between the controller and EF, which I do not like this solution is that sometime there are 200 different methods within a service and start giving me maintenance problems.

    
asked by anonymous 06.10.2015 / 03:09

1 answer

2

I did not need mockar to get the result I wanted. I just picked up the value that was already in the result and I did not know.

(This is not the case) I put a different way to mock%%.

In return I get the Indetify .

Follow the control and test code:

Controller:

[Authorize]
    public class DominioController : Controller
    {

        private IDominioDB _db;

        public DominioController(IDominioDB db)
        {
            _db = db;
        }

        // GET: Dominio
        public async Task<ViewResult> Index()
        {

            var userID = User.Identity.GetUserId();
            var d = await _db.Dominios.Where(x => x.idUsu == userID).ToListAsync();

            ViewBag.Username = User.Identity.Name;

            return View(d);
        }
    }

Test:

[TestMethod]
        public async Task VERIFICA_CONTROLE_DOMINIO()
        {

            //CRIANDO GENERICINDENTITY 
            string username = "Ricardo";
            string userid = "usuario1"; 

            List<Claim> claims = new List<Claim>{
                new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", username),
                new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", userid)
            };
            var genericIdentity = new GenericIdentity(username);
            genericIdentity.AddClaims(claims);

            var genericPrincipal = new GenericPrincipal(genericIdentity, new string[] { "Ricardo" });
            //*************************


            //CRIANDO BASE DE DADOS PARA TESTE E FAZENDO O MOCK DO CONTEXTO
            var data = new List<DBDominio>()
            {
                new DBDominio() { idUsu = "usuario1" },
                new DBDominio() { idUsu = "usuario2" },new DBDominio() { idUsu = "usuario2" },
                new DBDominio() { idUsu = "usuario3" },new DBDominio() { idUsu = "usuario3" }
            }.AsQueryable();

            var mockSet = new Mock<DbSet<DBDominio>>();
            //*************************


            mockSet.As<IDbAsyncEnumerable<DBDominio>>()
                .Setup(m => m.GetAsyncEnumerator())
                .Returns(new TestDbAsyncEnumerator<DBDominio>(data.GetEnumerator()));

            mockSet.As<IQueryable<DBDominio>>()
                .Setup(m => m.Provider)
                .Returns(new TestDbAsyncQueryProvider<DBDominio>(data.Provider));


            mockSet.As<IQueryable<DBDominio>>().Setup(m => m.Expression).Returns(data.Expression);
            mockSet.As<IQueryable<DBDominio>>().Setup(m => m.ElementType).Returns(data.ElementType);
            mockSet.As<IQueryable<DBDominio>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());

            var repo = new Mock<Interfaces.IDominioDB>();
            repo.Setup(c => c.Dominios).Returns(mockSet.Object);


            //AQUI AO CRIAR O MOCK DE CONTROLLER EU FAÇO O SETUP COLOCANDO O IDENTITY PARA RETORNAR O GENERICIDENTITY CRIADO ACIMA
            var context = new Mock<ControllerContext>();
            context.SetupGet(x => x.HttpContext.User.Identity).Returns(genericIdentity);


            //AO CRIAR O OBJETO CONTROLER EU PASSO O CONTEXTO COM O INDENTITY NELE.
            // Arrange
            DominioController controller = new DominioController(repo.Object)
            {
                ControllerContext = context.Object,

            };

            // Act
            ViewResult result = (ViewResult)await controller.Index();
            var resultModel = (IEnumerable<DBDominio>)result.Model;

            // Assert
            Assert.IsNotNull(result);
            Assert.AreEqual(result.ViewBag.Username , "Ricardo");
            Assert.AreEqual(resultModel.Count(), 1);

        }
    
07.10.2015 / 01:42