ailinmcc666
ailinmcc666

Reputation: 413

Can anybody show me what I'm doing wrong trying to test controller with call to unit of work?

I can't seem to figure this out, I have a C# MVC web application which uses entity framework, with a generic repository and unit of work.

I'm trying to test a controller method that uses unit of work to get a list of people, and I don't seem to be able to properly mock it! The error I get is:

System.ArgumentNullException: Value cannot be null.
Parameter name: source

I'll try and keep this as streamlined as possible, but if you want me to post more of my code I can do so. So, my code is as the following:

Controller

IQueryable<PERSON> people = unitOfWork.PersonRepository.GetAll();
var persontest = people.ToList();

There's more to this method, but it fails on the ToList(). The actual code is a lot more complicated, there's a lot more added to the IQueryable before the ToList() is called.

UnitOfWork

public class UnitOfWork : IUnitOfWork, IDisposable
{
    private DBContext context = new PASICSDBContextqlEntities();
    private IRepository<PERSON> personRepository;

    public IRepository<PERSON> PersonRepository
    {
        get
        {
            if (personRepository == null)
            {
                personRepository = new Repository<PERSON>(context);
            }
            return personRepository;
        }
    }

    public void Save()
    {
        context.SaveChanges();
    }

    private bool disposed = false;

    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                context.Dispose();
            }
        }
        disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

Repository

public class Repository <TEntity> : IRepository <TEntity> where TEntity: class
{
    internal PASICSqlEntities context;
    internal DbSet<TEntity> dbSet;

    public Repository(PASICSqlEntities context)
    {
        this.context = context;
        dbSet = context.Set<TEntity>();
    }

    public virtual IEnumerable<TEntity> Get(
        Expression<Func<TEntity, bool>> filter = null,
        Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
        string includeProperties = "")
    {
        IQueryable<TEntity> query = dbSet;

        if (filter != null)
        {
            query = query.Where(filter);
        }

        foreach (var includeProperty in includeProperties.Split
            (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
        {
            query = query.Include(includeProperty);
        }

        if (orderBy != null)
        {
            return orderBy(query).ToList();
        }
        else
        {
            return query.ToList();
        }
    }

    public virtual IQueryable<TEntity> GetAll()
    {
        return dbSet.AsQueryable();
    }

    public virtual TEntity GetByID(object id)
    {
        return dbSet.Find(id);
    }

    public virtual void Insert(TEntity entity)
    {
        dbSet.Add(entity);
    }

    public virtual void Delete(object id)
    {
        TEntity entityToDelete = dbSet.Find(id);
        Delete(entityToDelete);
    }

    public virtual void Delete(TEntity entityToDelete)
    {
        if (context.Entry(entityToDelete).State == EntityState.Detached)
        {
            dbSet.Attach(entityToDelete);
        }
        dbSet.Remove(entityToDelete);
    }

    public virtual void Update(TEntity entityToUpdate)
    {
        dbSet.Attach(entityToUpdate);
        context.Entry(entityToUpdate).State = EntityState.Modified;
    }

    public void ExecuteRawSql(string query, params object[] parameters)
    {
        dbSet.SqlQuery(query, parameters);
    }
}

TestController

public class HomeControllerTest
{
    private Mock<IUnitOfWork> _unitOfWorkMock;
    private HomeController _objController;
    private Mock<IRepository<PERSON>> _personRepository;

    [TestInitialize]
    public void Initialize()
    {
        _unitOfWorkMock = new Mock<IUnitOfWork>();
        _objController = new HomeController(_unitOfWorkMock.Object);
        _personRepository = new Mock<IRepository<PERSON>>();
        _personRepository.Setup(x => x.GetAll()).Returns(GetPersonList() as IQueryable<PERSON>).Verifiable();
    }

    [TestMethod]
    public void Index()
    {
        // Arrange
        _unitOfWorkMock.Setup(x => x.PersonRepository).Returns(_personRepository.Object);
        var viewModel = CreateIndexViewModelNoSearchParams();
        viewModel.SearchViewModel.Casenote = "CASENOTE1";

        // Act
        ViewResult result = _objController.Index(viewModel) as ViewResult;

        // Assert
        Assert.IsNotNull(result);
        Assert.AreEqual(1, viewModel.PersonViewModel.Count);
        Assert.AreEqual(2, viewModel.PersonViewModel[0].CasenoteList.Count);
        Assert.AreEqual("Index", result.ViewName);
    }

    #region Setup Methods

    private IndexViewModel CreateIndexViewModelNoSearchParams()
    {
        var viewModel = new IndexViewModel
        {
            SearchViewModel = new SearchViewModel
            {
                Hcn = null,
                Forename = null,
                Surname = null,
                Dob = null,
                Casenote = null
            }
        };
        return viewModel;
    }

    private List<PERSON> GetPersonList()
    {
        return new List<PERSON>
        {
            new PERSON
            {
                PAS_INT_NO = 1,
                SURNAME = "TEST SURNAME 1",
                FORENAMES = "TEST FORENAMES 1",
                DOB = new DateTime(2001,01,30),
                SEX = "M",
                GP_CODE = "TEST1",
                ADDRESS1 = "TEST ADDRESS1",
                ADDRESS2 = "TEST ADDRESS2",
                ADDRESS3 = "TEST ADDRESS3",
                ADDRESS4 = "TEST ADDRESS4",
                POSTCODE = "TESTPC1",
                CSA_NO = "1234567890",
                DEAD = "N",
                DATE_OF_DEATH = null,
                TITLE = "MR",
                DHA_CODE = "ABC",
                TELEPHONE = "1234567890",
                PREV_SURNAME_1 = null,
                PREV_SURNAME_2 = null,
                PREV_SURNAME_3 = null,
                MRSA_STATUS = null,
                MRSA_DATE = null
            },
            new PERSON
            {
                PAS_INT_NO = 2,
                SURNAME = "TEST SURNAME 2",
                FORENAMES = "TEST FORENAMES 2",
                DOB = new DateTime(2001,01,30),
                SEX = "M",
                GP_CODE = "TEST2",
                ADDRESS1 = "TEST ADDRESS1",
                ADDRESS2 = "TEST ADDRESS2",
                ADDRESS3 = "TEST ADDRESS3",
                ADDRESS4 = "TEST ADDRESS4",
                POSTCODE = "TESTPC2",
                CSA_NO = "1234567890",
                DEAD = "N",
                DATE_OF_DEATH = null,
                TITLE = "MR",
                DHA_CODE = "ABC",
                TELEPHONE = "1234567890",
                PREV_SURNAME_1 = null,
                PREV_SURNAME_2 = null,
                PREV_SURNAME_3 = null,
                MRSA_STATUS = null,
                MRSA_DATE = null
            },
            new PERSON
            {
                PAS_INT_NO = 3,
                SURNAME = "TEST SURNAME 3",
                FORENAMES = "TEST FORENAMES 3",
                DOB = new DateTime(2001,01,30),
                SEX = "M",
                GP_CODE = "TEST3",
                ADDRESS1 = "TEST ADDRESS1",
                ADDRESS2 = "TEST ADDRESS2",
                ADDRESS3 = "TEST ADDRESS3",
                ADDRESS4 = "TEST ADDRESS4",
                POSTCODE = "TESTPC3",
                CSA_NO = "1234567890",
                DEAD = "N",
                DATE_OF_DEATH = null,
                TITLE = "MR",
                DHA_CODE = "ABC",
                TELEPHONE = "1234567890",
                PREV_SURNAME_1 = null,
                PREV_SURNAME_2 = null,
                PREV_SURNAME_3 = null,
                MRSA_STATUS = null,
                MRSA_DATE = null
            },
            new PERSON
            {
                PAS_INT_NO = 4,
                SURNAME = "TEST SURNAME 4",
                FORENAMES = "TEST FORENAMES 4",
                DOB = new DateTime(2001,01,30),
                SEX = "M",
                GP_CODE = "TEST4",
                ADDRESS1 = "TEST ADDRESS1",
                ADDRESS2 = "TEST ADDRESS2",
                ADDRESS3 = "TEST ADDRESS3",
                ADDRESS4 = "TEST ADDRESS4",
                POSTCODE = "TESTPC4",
                CSA_NO = "1234567890",
                DEAD = "N",
                DATE_OF_DEATH = null,
                TITLE = "MR",
                DHA_CODE = "ABC",
                TELEPHONE = "1234567890",
                PREV_SURNAME_1 = null,
                PREV_SURNAME_2 = null,
                PREV_SURNAME_3 = null,
                MRSA_STATUS = null,
                MRSA_DATE = null
            }
        };
    }
    #endregion  
}

Sorry, I didn't keep that streamlined at all! I have no idea what I'm doing, and I can't find any good sources for learning this stuff. Because there's so many ways of implementing IoC, unit of work, repositories, services, etc, there's lots of different help out there for unit testing, but I can't apply it to my work. Help!

Upvotes: 2

Views: 61

Answers (1)

Nkosi
Nkosi

Reputation: 247213

The cast in Initialize() here

....Returns(GetPersonList() as IQueryable<PERSON>)...

is the problem.

Since GetPersonList() returns List<PERSON>, then GetPersonList() as IQueryable<PERSON> will cause the cast to result in null

refactor the Returns to

_personRepository
    .Setup(x => x.GetAll())
    .Returns(GetPersonList().AsQueryable())
    .Verifiable();

Upvotes: 2

Related Questions