none
Unit Test project issue RRS feed

  • Question

  • Hi,

    I am using EFCore 2.1, I have created a a Unit test project, 

    Our project has service and Repository classes. When service class calling Repository method then raising no source avaiable error.   It look like iRepository not mapped with the inherited class "Repository"

    How may i solve this issue?

    public class TestClass
    {
    private Mock<iRepository> mockRepo;
    private DataService ds;

    public void TestClass()
    {
    mockRepo= new Mock<repository>();
    mockRepo.Setup(repo => repo.GetListAsync()).Returns(Task.FromResult(null));
    ds = new DataService(mockRepo.object) 
    }

    private async Task GetList(Person p)
    {
    List<classmodel> list = await ds.GetListAsync();
    }
    }

    ===================================

    public class DataService {

    IRepository _repo;
    public DataService(Repository repo) { 
    _repo = repo;
    }

    public async Task<List<classmodel>> GetListAsync(){
    _repo.GetList();


    }

    ===================================

    public class Repository : IRepository {
    public async Task<List<classmodel>> GetListAsync(){
    _dbcontext.GetList();

    }


    • Edited by Amit m Thursday, November 15, 2018 2:29 PM
    Thursday, November 15, 2018 2:27 PM

All replies

  • Unless dbcontext is mocked, it seems that you are going to have a problem, as the method below tries to do it for real and go get some data, which is not a unit test if that happens.  

    _dbcontext.GetList();

    https://www.jankowskimichal.pl/en/2016/01/mocking-dbcontext-and-dbset-with-moq/

    Also, learn how to use Arrange, Act and Assert. 

    http://defragdev.com/blog/?p=783

    Finally learn how to post code in a formatted manner by using the 'Code Format' tool that is on the toolbar =, an icon that is to the right of the HTML icon on the toolbar. 


    Thursday, November 15, 2018 3:47 PM
  • Thanks, I raised my issue in mention post, May you please help more to troubleshoot the issue?
    Friday, November 16, 2018 5:22 AM
  • IMO, you shouldn't be unit testing the DataService. What should be unit tested is the Repository object with everything the Repository object is calling being mocked out and returning mocked data that you have setup at the Arrange.

    If you want to test the Dataservice, then you should be using an integration test.

     
    Friday, November 16, 2018 10:26 AM
  • Thanks for reply.  My service classed inject Repository object, Any service class may have some business logic before doing any get/add/update/delete operation. So I don't want to test Repository object directly, I want to do it through Service classes, How may i test service class in Unit Test project?

    Please check below code, when DataService class access Repository class object then it said no source code available, I  checked Repository classes doesn map with iRepository interface properly. Please suggest if you  have any solution?

    private Mock<iRepository> mockRepo;
    private DataService ds;

    public void TestClass()
    {
    mockRepo= new Mock<repository>();
    mockRepo.Setup(repo => repo.GetListAsync()).Returns(Task.FromResult(null));
    ds = new DataService(mockRepo.object) 
    }


    • Edited by Amit m Friday, November 16, 2018 1:55 PM
    Friday, November 16, 2018 1:50 PM
  • I can't help you,  becuase your architecture of injecting the repository object into the dataservice is unorthodox architecture. 
    Saturday, November 17, 2018 6:07 PM
  • You mean, Its not a good design, But let say i have to work with multiple repository and want to apply some business logic over multiple entities then want to save with in a transaction, then which architecture should be use?

    Please suggest a batter way if you can.

    One another question:

    Why Mock instance give "No source available" exception?

    Thanks.



    • Edited by Amit m Monday, November 19, 2018 7:03 AM
    Monday, November 19, 2018 3:59 AM
  • There is nothing wrong with the repository pattern. I am not a fan of the generic repository pattern, because it is too generic. The is nothing wrong in using a Repository object per business needs, which could be used  in a transaction scope across multiple Repository objects.

    Your DataService object is mapping technology that should be DI into the Repository object. And the advantage in DI of DS object into Repository object is so that the DS object can be mocked out in a unit test.

    You should understand the Repository pattern.

    https://martinfowler.com/eaaCatalog/repository.html

    Some things you shouldn't do with Repository object.

    https://programmingwithmosh.com/entity-framework/common-mistakes-with-the-repository-pattern/

    Your testing and mocking should be about mocking data that is to be retuned out of a mocked object's method during the Act, which would be verified on an Assert that the mocked data was returned out of the mocked object's method. Also,  Asserting that  the a method in a mocked object was run during the Act of running the code to be tested.

    The unit test is for a generic repository, but it points out the usage of Arrange Act Assert in unit testing.

    https://www.codeproject.com/Articles/741207/Repository-with-Unit-of-Work-IoC-and-Unit-Test

    On the other hand, if the Repository for the application is anemic, then I don't use the Repository pattern and use the DAO pattern wiith the DTO pattern, becuase the Repository object would be just a glorified DAO.

    https://blog.sapiensworks.com/post/2012/11/01/Repository-vs-DAO.aspx

    https://en.wikipedia.org/wiki/Data_access_object

    https://www.tutorialspoint.com/design_pattern/data_access_object_pattern.htm

    https://www.codeproject.com/Articles/1050468/Data-Transfer-Object-Design-Pattern-in-Csharp

    You want to test the Dataservice layer, then use an integration test using live data and test it for real. But for unit testing of the Repository object you should mock out the DataService object that is DI into the Repository object, plain and simple as to what you should be doing.

     

    .



    Monday, November 19, 2018 8:06 AM