13

I am fairly new to unit testing and I am trying to create a unit test for a Web API contoller that I have created which returns a list of brands.

My Web API controller Get() method looks like this:

[HttpGet("/api/Brands/Get", Name = "GetBrands")]
public async Task<IActionResult> Get()
{
    var brands = await _brandsService.GetAll(null, "Image");
    return Json(brands);
}

The generic service method looks like this:

public async Task<List<T>> GetAll(
    Func<IQueryable<T>, 
    IOrderedQueryable<T>> orderBy = null, 
    string includeProperties = null)
{
    return await _genericRepository.GetAll(orderBy, includeProperties);
}

and the generic repo method looks like this:

public async Task<T> Get<TKey>(Expression<Func<T, bool>> filter = null, string includeProperties = "", bool noTracking = false)

{
    includeProperties = includeProperties.Trim() ?? string.Empty;
    IQueryable<T> query = Context.Set<T>();

    if (noTracking)
    {
        query.AsNoTracking();
    }

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

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

    return await query.SingleOrDefaultAsync();
}

This is working and I am returning a list of brands from the database.

Now I tried to create a Unit test for this:

[SetUp]
public void Setup()
{
    Brands = new List<Brand>
    {
        new Brand
        {
            Id = 1,
            Name = "Adidas",
            ImageId = 1
        },
        new Brand
        {
            Id = 2,
            Name = "Nike",
            ImageId = 2
        },
        new Brand
        {
            Id = 3,
            Name = "Puma",
            ImageId = 3
        }
    };
}

[Test]
public async Task Get_ReturnsAAListOfBrands()
{
    //Arrange
    var mockService = new Mock<IGenericService<Brand>>();
    mockService.Setup(repo => repo.GetAll(null, null)).Returns(Task.FromResult(Brands));
    var controller = new BrandsController(mockService.Object);

    //Act
    var result = await controller.Get();
    //Assert
}

however the result is always null. Am I testing this correctly or do I need to change my unit test code to verify that the mock service has three items stored?

13
  • I think you need to setup the return of query.SingleOrDefaultAsync(), although you would need to check how to do this as query is not passed in to the constructor. This question may help stackoverflow.com/questions/41611795/… Commented Jan 18, 2017 at 14:42
  • thanks @Alex I will check that question out Commented Jan 18, 2017 at 14:43
  • yes same problem I am having, GetAll(null,null) does not seem to be getting hit in the debugger Commented Jan 18, 2017 at 14:50
  • use the It.IsAny<T> methods if the arguments are of no consequence to the test Commented Jan 18, 2017 at 14:52
  • @Johann The debugger will not enter the method, you need to simulate the return value using setup. Commented Jan 18, 2017 at 14:54

1 Answer 1

8

You need to configure the setup to expect a particular behavior or argument for the test.

In this case using the It.IsAny<T>() to tell the set up what to expect in terms of arguments will allow the test to flow as desired.

Given that the GetAll method requires two parameters of Func<IQueryable<T>, IOrderedQueryable<T>> and string, the setup configures what to do based on the values entered for those parameters.

[Test]
public async Task Get_ReturnsAAListOfBrands() {
    //Arrange
    var mockService = new Mock<IGenericService<Brand>>();
    mockService
        .Setup(repo => repo.GetAll(It.IsAny<Func<IQueryable<Brand>, IOrderedQueryable<Brand>>>(), It.IsAny<string>()))
        .ReturnsAsync(Brands);
    var controller = new BrandsController(mockService.Object);

    //Act
    var result = await controller.Get();
    //Assert
    //...
}

Take a look at the Moq Quickstart for a better understanding of how to use this mocking framework

Sign up to request clarification or add additional context in comments.

5 Comments

just as I was going to type that I had solved it, saw your code here :) Thanks will add this as the anwer!
yes I have to investigate mocking better, that is why I am doing some examples. Thanks for your help
This example helped me a lot to come to the answer stackoverflow.com/questions/35565353/…
just one last thing, how can I verify that the result.Count() is actually 3? My JsonResult does not seem to allow me to see the Data, and I cannot get the Count() from the Value:- JsonResult actualResult = await controller.Get() as JsonResult; var data = actualResult.Data;
Now it is a little tricky. This is however not the first time I've encountered this. check my answer here and see if it applies to your situation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.