0

Hello i have a project web api in c# and i want to write unit test to check my controller. But i find an error that i really don't understand. When i run my method in controller

public class TherapistsController : ApiController
{
    TherapistService _therapistService = new TherapistService();
    GeneralService _generalService = new GeneralService();

    //GET: api/Therapists/GetAllTherapists
    [HttpGet]
    [Route("api/Therapists/GetAllTherapists")]
    public IHttpActionResult GetTherapist()
    {
        var therapists = _therapistService.GetAllTherapist();
        if (therapists.Count() > 0)
            return Ok(therapists);
        return NotFound();
    }
}

it give me the result and it is fine enter image description here

But if i run this method in a unit test

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void GetAllTherapistByOutletTest()
    {
        var therapists = new WebAPI.Controllers.TherapistsController();

        IHttpActionResult result = therapists.GetTherapist();

        Assert.IsInstanceOfType(result, typeof(OkResult));

    }
}

it give me the error

enter image description here

Like u see the error says that i need to update database by migration but it still give me same error after i migrate and update database. But when i run the method by calling API ,it still give me the result like the first picture and no error. I debug both ways and they have same steps until method GetAll() in repository like u see in the above picture. I don't really know what wrong ?

Repository

public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class
{
    protected readonly SpaDbContext db;
    public GenericRepository(SpaDbContext _db)
    {
        this.db = _db;
    }
    public void Add(TEntity entity)
    {
        db.Set<TEntity>().Add(entity);
    }

    public void AddRange(IEnumerable<TEntity> entities)
    {
        db.Set<TEntity>().AddRange(entities);
    }

    public void Detached(TEntity entity)
    {
        db.Entry<TEntity>(entity).State = EntityState.Detached;
    }

    public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
    {
        return db.Set<TEntity>().Where(predicate);
    }    

    public TEntity Get(Expression<Func<TEntity, bool>> predicate)
    {
        return db.Set<TEntity>().FirstOrDefault(predicate);
    }

    public TEntity Get(object Id)
    {
        return db.Set<TEntity>().Find(Id);
    }

    public IEnumerable<TEntity> GetAll()
    {
        return db.Set<TEntity>().ToList();
    }

    public void Remove(TEntity entity)
    {
        db.Set<TEntity>().Remove(entity);
    }

IRepository

namespace Repository
{
    public interface IGenericRepository<TEntity> where TEntity : class
    {
        IEnumerable<TEntity> GetAll();
        IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate);
        TEntity Get(Expression<Func<TEntity, bool>> predicate);
        TEntity Get(object Id);
        void Add(TEntity entity);
        void AddRange(IEnumerable<TEntity> entities);
        void Update(TEntity entity);

        //void Remove(object Id);
        void Remove(TEntity entity);
        void RemoveRange(IEnumerable<TEntity> entities);

        void Detached(TEntity entity);

        IEnumerable<TEntity> GetByQuery(string query);
    }
}
8
  • What exactly are you trying to 'test'? I'm guessing EF hasn't gone through the necessary initialisation in your test when you simply new up the controller. So you don't rely on database access in your tests, I'd advise you abstract out the services, have them as dependencies on the controller (constructor) then you can mock and assert calls on them without going near any databases. Commented Dec 5, 2018 at 19:05
  • You probably have a different connection string for each of the 2 contexts. Commented Dec 5, 2018 at 19:13
  • i just want to test the method return ok or not . i don't understand " abstract out the services" . Can u describe how to do it briefly ? Commented Dec 5, 2018 at 19:15
  • 1
    @Van try this, I hope it makes sense dotnetfiddle.net/kmz925. FYI it's pseudo code (won't compile) but should explain the concepts. Commented Dec 5, 2018 at 19:28
  • 1
    dotnetfiddle.net/CqX3xY has an updated example with the 'abstraction' which is an interface. Commented Dec 5, 2018 at 19:35

2 Answers 2

2

Make sure you have set a valid connection string in test project as web api project

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

1 Comment

yeah thank you. this is the problem , i haven't set up my connection string in UnitTest project
0

If you want do a real unit test with the controller methods you need use Mock services with this you will not have this kind of problems

https://learn.microsoft.com/en-us/aspnet/web-api/overview/testing-and-debugging/unit-testing-controllers-in-web-api

Comments

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.