0

I am trying to unit test a controller which takes in a dbcontext and a usermanager object. How could I go about passing these into the controller when performing unit testing?

Controller

public ProjectsController(ApplicationDbContext context,
    UserManager<ApplicationUser> userManager)
{
    _context = context;
    _userManager = userManager;
}

ApplicationDbContext

public ApplicationDbContext(
    DbContextOptions options,
    IOptions<OperationalStoreOptions> operationalStoreOptions) : base(options, operationalStoreOptions)
{


}

public DbSet<Project> Projects { get; set; }

Test

[Fact]
public void test4()
{
//....
    var controller = new ProjectsController(null, null);
    var result = controller.GetProject(p.ProjectId);
}

Controller method being tested

[HttpGet("{id}")]
public async Task<ActionResult<Project>> GetProject(Guid id)
{
    var project = await _context.Projects.FindAsync(id); // Find project by id
    var query = _context.Users.Where(u => u.Projects.Any(p => p.ProjectId.ToString().Equals(project.ProjectId.ToString()))); //find all users for the project
    project.AssignedUsersToProject = query.ToList(); //set found users to the assigned users list

    if (project == null)
    {
        return NotFound();
    }

    return project;
}
Krellex
  • 613
  • 2
  • 7
  • 20
  • You probably want to mock the dependencies, e.g. with "Moq" library (https://github.com/moq/moq4). Here is an example for mocking UserManager: https://stackoverflow.com/questions/55412776/how-to-mock-usermanageridentityuser. Hope it can help you get started – thesystem Dec 09 '21 at 09:30
  • Thanks for this. How might I go about mocking the DbContext to pass the controller? doing `var mockDB = new Mock();` did not seem to work for me. Passing `mockDB.Object` – Krellex Dec 09 '21 at 09:51
  • I would suggest to use InMemory-database. You can see example here: https://stackoverflow.com/questions/54219742/mocking-ef-core-dbcontext-and-dbset – thesystem Dec 09 '21 at 10:53
  • @thesystem Thanks for the reply. The link looks really good but I find myself in an issue where I do not know what to be passing for the second param of my dbcontext `IOptions operationalStoreOptions` and so when I try and do `var context = new ApplicatinDbContext(options))` it expects another param filled – Krellex Dec 09 '21 at 12:50
  • Your `operationalStoreOptions` looks incomplete. It should be sorta like: `var options = new DbContextOptionsBuilder().UseInMemoryDatabase("NameOfYourDatabase").Options;` – thesystem Dec 09 '21 at 12:56
  • @thesystem Thanks for getting back. I am a little confused on how this would help me test my http method in my controller – Krellex Dec 09 '21 at 12:59
  • I understand that, I dont know if I am the best to it explain it. But you want to use an "InMemory" database, so that you are not testing against your real database - that would be an integration test. Thats also why we want to mock other dependencies – thesystem Dec 09 '21 at 13:34
  • @thesystem Ah okay. Thanks for taking the time to help me out! – Krellex Dec 09 '21 at 18:13
  • Don't mock, please . – Fabio Dec 15 '21 at 05:33
  • I want to test against real database, because only real database provide real feedback on my code. I don't care how somebody will name such tests ;) – Fabio Dec 15 '21 at 05:38

0 Answers0