1

I'm trying to implement search by passing the keyword to controller action as a parameter as shown below:

public ActionResult Index(string query)
{
    var contacts = _unitOfWork.Contacts.GetContacts(_user.Id, query);
    var viewModel = contacts.Select(Mapper.Map<Contact, ContactViewModel>);
    return View("Index", viewModel); 
}

GetContacts function in the repository looks like the following:

public IEnumerable<Contact> GetContacts(int userId, string query = null)
{
    var list = _context.Contacts
                    .Where(c => c.UserId == userId)
                    .OrderBy(c => c.FirstName)
                    .AsQueryable();

    if (query != null)
        list = list.Where(c => c.FirstName.ToLower().Contains(query.ToLower())
        || c.LastName.ToLower().Contains(query.ToLower()));

    return list.ToList();
}

When I navigate to http://localhost:50139/contacts/index?query=, I get an empty list. Having stepped through the code it is apparent that the query parameter is converted to an empty string value. To ensure the search works, I have the following tests and all of them pass:

GetContacts_SearchByFirstName_ShouldReturnFilteredList
GetContacts_SearchByLastName_ShouldReturnFilteredList
GetContacts_SearchWithCapitalLetters_ShouldReturnFilteredList
GetContacts_SearchWithNullQuery_ShouldReturnAllContacts

In particular, the following test runs the function with empty string, which also passes successfully.

[TestMethod]
public void GetContacts_SearchWithEmptyString_ShouldReturnAllContacts()
{
    var contactList = new List<Contact>()
    {
        // Construct new contact with first and last name and associated user id. 
        new Contact("e", "b",_userId ),
        new Contact("c", "b",_userId ),
        new Contact("a", "b",_userId ),
        new Contact("d", "b",_userId )
    };

    _mockContacts.SetSource(contactList);

    var result = _repository.GetContacts(_userId, "");

    result.Count().Should().Be(4);
}

I have 3 contacts in the database and I can see all of them when I don't pass the query parameter. I would appreciate if you could point out why the controller action returns an empty list.

1
  • Try using String.IsNullOrEmpty instead of query != null Commented Nov 29, 2016 at 10:44

2 Answers 2

2

When you pass an empty string to the query parameter, the condition if(query!=null) fails and the line below that

list = list.Where(c => c.FirstName.ToLower().Contains(query.ToLower())
            || c.LastName.ToLower().Contains(query.ToLower()));

gets executed, which checks the database for an entry with empty string in the LastName. This condition never gets satisfied and hence your list gets overridden with an empty list.

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

Comments

2

change if (query != null) to if (!string.IsNullOrEmpty(query))

3 Comments

The question is why the controller action returns an empty list?
@StephenMuecke Yes and the answer is because of wrong if Statement.
No, OP is claiming their unit test passes (but I suspect their claim is wrong because I can repeat it)

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.