Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic Moq Repository - GetById(int i) returns T

Tags:

generics

moq

I have a generic repository and im trying to create a moq implementation for my unit tests. I need to create a GetById method. This is the moq implementation before i decided to convert it to use generics.

mockUserRepository.Setup(r => r.GetById(It.IsAny<int>()))
.Returns((int i) => users.Where(u => u.Id == i).Single());

A generic repository will be used for the MOQ setup

Mock<IRepository<T>> mockRepository

A generic list of fakes will be used for the LINQ where clause

List<T> list

Can anyone help me convert the method above.

like image 662
ministrymason Avatar asked Nov 23 '25 14:11

ministrymason


1 Answers

I'm not entirely sure what you're asking. If you just want to create a mock of the generic repository, the setup is the same.

If you want a helper method to create a repository for any entity type, that's doable. You have to either implement an interface on the entities to retrieve the ID or pass in a delegate to the helper method. Here's a LINQPad example that shows the first technique.

void Main()
{
    var users = new List<User>
        { new User { Id = 1 }, new User { Id = 2 } };

    var mockUserRepository = new Mock<IUserRepository>();

    mockUserRepository.Setup(r => r.GetById(It.IsAny<int>()))
        .Returns((int i) => users.Where(u => u.Id == i).Single());

    mockUserRepository.Object.GetById(2).Dump();

    var mockUserRepository2 = new Mock<IRepository<User>>();

    mockUserRepository2.Setup(r => r.GetById(It.IsAny<int>()))
        .Returns((int i) => users.Where(u => u.Id == i).Single());

    mockUserRepository2.Object.GetById(2).Dump();

    IRepository<User> userRepository3 = CreateTestRepository(users);

    userRepository3.GetById(2).Dump();
}

public static IRepository<TEntity> CreateTestRepository<TEntity>(
    List<TEntity> entities)
    where TEntity: IPrimaryKeyed
{
    var mockRepository = new Mock<IRepository<TEntity>>();

    mockRepository.Setup(r => r.GetById(It.IsAny<int>()))
        .Returns((int i) => entities.Where(e => e.Id == i).Single());

    return mockRepository.Object;
}

public interface IPrimaryKeyed
{
    int Id { get; }
}

public class User : IPrimaryKeyed
{
    public int Id { get; set; }
}

public interface IUserRepository
{
    User GetById(int id);
}

public interface IRepository<T>
{
    T GetById(int id);
}

As an aside, assuming your IDs will always be integers is risky. You might consider making the int type generic (when used to refer to IDs/primary keys) throughout your codebase. Normally I'd invoke YAGNI, but searching and replacing int with Guid does not work well. ;)

like image 120
TrueWill Avatar answered Nov 28 '25 17:11

TrueWill



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!