Unit test for function with func param using C# and Moq

41 Views Asked by At

How to write unit test for function with func param.

I am new to Moq framework and this is quite difficult understand how the behavior should be tested.

public class MongoDBRepository<TEntity> : IRepository<TEntity>
            where TEntity : EntityBase
{
    private readonly IMongoCollection<TEntity> collection;

The GetData method is declared as virtual, will it affect on writing test.

public virtual IEnumerable<TEntity> GetData(
        Expression<Func<TEntity, bool>> filter = null)
    {
        lock (this.collectionLock)
        {
            try
            {
                if(filter == null)
                {
                    filter = _ => true;
                }

                return this.collection
                    .AsQueryable<TEntity>()
                    .Where(filter.Compile())
                    .ToList();

            }
            catch (Exception e)
            {
                this.logger.LogError($"Query Failed", e);
                return new List<TEntity>();
            }
        }
    }
1

There are 1 best solutions below

2
JonasH On

If the goal is to test the code that fetches data from the database I would recommend writing an test that uses an actual database. Otherwise there is a significant risk that the test do not match the real behavior of the database.

This includes any code that provides an expression, since it will depend on how the database provider translates that expression. There are plenty of queries that work just fine against an in-memory collection, but cannot be translated to a real database query. You might also want to separate such code from the rest of the system as much as possible, to make testing of the database easier.

For this to be practical you need an easy way to create a fresh database, with any required data, ideally created from the same script you use to setup new systems. You can then run your tests, and delete the database once everything is done.

Note some things to consider

  • Should the database be installed on each machine? Or should you have a centralized database for testing?
  • How to prevent different automated tests from interfering with each other?
  • Performance? creating databases may be a relatively slow process. Perhaps use attributes or a separate project to separate fast tests from slower database tests?
  • How to prevent garbage data from accumulating for old or failed tests?

You may want to take a look at the in memory database provider, but I'm not sure if it is a good representation of a mongoDb or not.