Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FindAsync is not working properly #33

Closed
risogolo opened this issue Jun 16, 2020 · 7 comments
Closed

FindAsync is not working properly #33

risogolo opened this issue Jun 16, 2020 · 7 comments
Assignees

Comments

@risogolo
Copy link

risogolo commented Jun 16, 2020

I saw it, similar has been discussed already, but it does still not work on my end

I have

var countries = CountryStub.GetCountries().AsQueryable().BuildMockDbSet(); // 3 items (1st is Id:1)
            _uow.Setup(x => x.Context.Set<Country>()).Returns(countries.Object);
            _uow.Setup(x => x.Context.Set<Country>().FindAsync(1)).ReturnsAsync(new Country { Id:1 }); // and I dont want to do this, collection contains that item already
            var repository = new CountryRepository(_uow.Object);
            var result = await repository.FindByIdAsync(1); //it calls FindAsync internally and result is null

and I would expect once I mock context Country that FindAsync method should return item with id:1

@romantitov
Copy link
Owner

romantitov commented Jun 16, 2020

@risogolo thanks for the issue. I'm not sure that _uow.Setup(x => x.Context.Set<Country>().FindAsync(1)).ReturnsAsync(new Country { Id:1 }) is proper way how FindAsync should be configured. I would suggest you more carefully have a look similar issue #7 with code example.
in short, try to set up FindAsync for countries instead of _uow. Please let me know if it helped.

@risogolo
Copy link
Author

risogolo commented Jun 17, 2020

Im sorry it still does not work on my side

private Mock<IOrderManagerUnitOfWork<OrderManagerContext>> _uow = new Mock<IOrderManagerUnitOfWork<OrderManagerContext>>();
 var countries = CountryStub.GetCountries().AsQueryable().BuildMockDbSet(); // GetCountries()r returns List<Country>
            countries.Setup(x=>x.FindAsync(1)).ReturnsAsync((object[] ids) =>
            {
                return countries.Object.FirstOrDefault(x => x.Id == 1);
            }); //also why I should do this, Im basically mocking the data (DbSet), so I expect the linq extension methods will work on mocked collection
            _uow.Setup(x => x.Context.Set<Country>()).Returns(countries.Object);
            var repository = new CountryRepository(_uow.Object); //passing context containing mocked DbSet wrapped in UOW
            var result = await repository.FindByIdAsync(1); //internally calls FindAsync(id)
            Assert.IsNotNull(result); //still null

@romantitov
Copy link
Owner

@risogolo instead of return countries.Object.FirstOrDefault(x => x.Id == 1); I would suggest CountryStub.GetCountries().FirstOrDefault(x => x.Id == 1); because FindAsync should return items from real data, you can also see it in my example #7

Not sure if the line will work:
_uow.Setup(x => x.Context.Set<Country>()).Returns(countries.Object); not sure if the part of code x.Context.Set<Country>() will return you your mock object. I would suggest you to implement IOrderManagerUnitOfWork in a test class and then use it in your tests. Something like this:

internal class MyTestClass: IOrderManagerUnitOfWork<OrderManagerContext>{
    DbSet<Country> _countryDbset;
   public MyTestClass(DbSet<Country> countryDbset){
           _countryDbset = countryDbset;
    }
   ...
    public Set<Country>
   {
         get{
               return _countryDbset;
          }
   }
   ...
} 

@risogolo
Copy link
Author

risogolo commented Jun 17, 2020

My intention was to mock data in DbSet, not FindAsync method, I expected that FindAsync will return the data from mocked DbSet.

Anyway, so the first suggestion to return CountryStub.GetCountries().FirstOrDefault(x => x.Id == 1); instead does not work and this
_uow.Setup(x => x.Context.Set<Country>()).Returns(countries.Object); for getting the list from repository works correctly for the tests where I'm testing collections to be returned from repository method, but not for the FindAsync

@risogolo
Copy link
Author

risogolo commented Jun 17, 2020

but this works

 countries.Setup(x => x.FindAsync(It.IsAny<object[]>())).ReturnsAsync((object[] ids) =>
            {
                return CountryStub.GetCountries().FirstOrDefault(x => x.Id == 1);
            }); 

but this is not

object[] args = new object[1];
args[0] = 1;
 countries.Setup(x => x.FindAsync(args)).ReturnsAsync((object[] ids) =>
            {
                return CountryStub.GetCountries().FirstOrDefault(x => x.Id == 1);
            });

@romantitov
Copy link
Owner

If you can provide full code, I'll help you more. but looks like the issue is not related to the project.

@romantitov
Copy link
Owner

@risogolo FindAsync(It.IsAny<object[]>() works as expected for me.

  var mock = users.AsQueryable().BuildMockDbSet();
      mock.Setup(x => x.FindAsync(It.IsAny<object[]>())).ReturnsAsync((object[] ids) =>
      {
        var id = (Guid) ids.First();
        return users.FirstOrDefault(x => x.Id == id);
      });

I have added a unit test for FindAsync case as example: DbSetFindAsyncUserEntity

@romantitov romantitov self-assigned this Jun 18, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants