GithubHelp home page GithubHelp logo

scott-xu / entityframework.testing Goto Github PK

View Code? Open in Web Editor NEW

This project forked from rowanmiller/entityframework.testing

102.0 102.0 25.0 1.1 MB

EntityFramework Testing

License: Apache License 2.0

C# 100.00%

entityframework.testing's People

Contributors

flynnious avatar justinyoo avatar mattbrooks2010 avatar migig avatar recaro avatar rowanmiller avatar scott-xu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

entityframework.testing's Issues

Add to readme some explanation/links about Ninject.MockingKernel

Could you please add to readme some explanation/links, why we should consider to use Ninject.MockingKernel.NSubstitute instead of just mocking framework.

Could you also remove dots in packages names.
The actual Nuget packages are EntityFrameworkTesting, not EntityFramework.Testing.

Suggested Enhancement: Add a second optional find method to better imitate DbSet.Remove

I wanted to use the DbSet.Remove method in some repository tests, but found that the mock DbSet.Remove method was only doing reference comparison. So passing in an object with identical property values (including the primary key) to an existing item in the collection wouldn't cause it to be removed.

My fix was to update the SetupData extension method signature to add an optional "findEntity" parameter:

public static Mock<DbSet<TEntity>> SetupData<TEntity>(
  this Mock<DbSet<TEntity>> mock,
  ICollection<TEntity> data = null,
  Func<object[], TEntity> find = null,
  Func<TEntity, TEntity> findEntity = null
) where TEntity : class

And then modify the Remove/RemoveRange callbacks to call it:

mock.Setup(m => m.Remove(It.IsAny<TEntity>())).Callback<TEntity>(entity =>
{
    if (findEntity != null) entity = findEntity(entity);
    data.Remove(entity);
    mock.SetupData(data, find, findEntity);
});

mock.Setup(m => m.RemoveRange(It.IsAny<IEnumerable<TEntity>>())).Callback<IEnumerable<TEntity>>(entities =>
{
    foreach (var entity in entities)
    {
        if (findEntity != null) entity = findEntity(entity);
        data.Remove(entity);
    }

    mock.SetupData(data, find, findEntity);
});

I then setup my mock to compare primary keys instead of object references:

_mockDbSet.SetupData(_testData, 
  find: ids => _testData.Find(e => e.EntityId == (int)ids[0]),
  findEntity: en => _testData.FirstOrDefault(e => en != null && e.EntityId == en.EntityId)
);

Finally, I modified the Add/AddRange callbacks to retain the findEntity parameter:

mock..Setup(m => m.Add(It.IsAny<TEntity>())).Callback<TEntity>(entity =>
{
    data.Add(entity);
    mock.SetupData(data, find, findEntity);
});

mock.Setup(m => m.AddRange(It.IsAny<IEnumerable<TEntity>>())).Callback<IEnumerable<TEntity>>(entities =>
{
    foreach (var entity in entities)
    {
        data.Add(entity);
    };

    mock.SetupData(data, find, findEntity);
});

Not sure if there's a better way of doing this, but I think it's a helpful enhancement since DbSet.Remove() is often passed a deserialized object from the service layer rather than an object that was constructed by EF, so the expected behaviour is a primary key comparison, not an object reference comparison.

Using MockBehavior.Strict

Hi guys!
I tried to make a mock for my simple DbContext and It works fine For MockBehavior.Default, But when I try to use MockBehavior.Strict I cannot even get an Object of this mock.

I made some workaround for one exception using additional Setup for Set<> method:

_myContextMock.Setup(x => x.MyEntities).Returns(mockSetObject);
_myContextMock.Setup(x => x.Set<MyEntity>()).Returns(mockSetObject);

but now got:

System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation.
  ----> Moq.MockException : IEnumerable.GetEnumerator() invocation failed with mock behavior Strict.
All invocations on the mock must have a corresponding setup.

And it is when I try to get an Object of my Mock, I mean when I use _myContextMock.Object

Next release?

Hi,
Thanks for this great library, we use it a lot in our EF6 projects. We also use NSubstitute and would like to upgrade this to version >=2.0 which is incompatible with the current version of this library. I can see you've committed a patch to fix this dependency (a9a7456), when do you expect to release a new version of the library to NuGet.org?

FakeItEasy version

I went back to a project and while upgrading packages I noticed that the EntityFramework.Testing.FakeItEasy NuGet package does support the latest version of FakeItEasy which is currently v2.2.0?

Are their plans to support versions of FakeItEasy > 2.0.0?

Support v4.5.1?

Currently it is compiled against .Net v4.5 which limits its usability in projects targeted to v4.5.1. Would be great to get this to support v4.5.1.

DbSet.Find() and DbSet.FindAsync() not working

My setup:

[TestFixture]
    public class SmsServicesTestsMockedProvider
    {
        private List<Company> _companySet;
        

        [SetUp]
        public void Setup()
        {

            _companySet = new List<Company>
            {
                new Company
                {
                    Id = 1,
                    Name = "Salão da Marta",
                    SmsCredit = 1,
                    SmsBonus = 1
                }
            };
            var companySetMock = new Mock<DbSet<Company>>().SetupData(_companySet);

            var dbMock = new Mock<AmezzeIdentityContext>(MockBehavior.Loose);
            dbMock.Setup(ctx => ctx.Companies).Returns(companySetMock.Object);

        }
    }

My test method calling a service class which uses the context internally:

       [Test]
        public async Task it_charges_bonus_sms_from_company()
        {
            var sms = SMS.Types.Sms
                .Create(_martaCompanyType, Message.CreateSafeMessage("This will cost 1 SMS bonus"), Destination.Create(_clientType, _mobileType));

            var smsStatus = await _smsService.TrySendSmsWithCharges(sms); // <-- The calling point
            
            Assert.NotNull(smsStatus);
            
            Assert.IsTrue(smsStatus.Successful);

            Assert.Zero(_companySet.First(x => x.Id == _martaCompanyType.CompanyId).SmsBonus);
            Assert.NotZero(_companySet.First(x => x.Id == _martaCompanyType.CompanyId).SmsBonus);
        }

The method using the context:

        public async Task<ISmsStatus> TrySendSmsWithCharges(Sms sms)
        {
            //This line is returning null
            var company = _context.Companies.Find(sms.Sender.CompanyId);

        }

If I use .ToList() it correctly returns the data from the List<Company> I've setup.
If I use .FirstOrDefault(x => x.Id == 1) it also works.
Thus I'm assuming it is really a bug with the .Find() and .FindAsync() methods.

The package EntityFrameworkTesting.Moq 1.2.1 targets .NET 4.6.1 when will a compatible package be developed for .NET Core?

I get a warning when building my .NET Core application that includes this NUget package for my unit test project:

"Warning NU1701 Package 'EntityFrameworkTesting.Moq 1.2.1' was restored using '.NETFramework,Version=v4.6.1' instead of the project target framework '.NETCoreApp,Version=v2.0'. This package may not be fully compatible with your project. TaskManager.Tests E:\Documents\Development Projects\Imparta Task Manager Technical Test\TaskManager\TaskManager.Tests\TaskManager.Tests.csproj 1 "

Will you create a version that targets .NET Core 2.0 and upwards?

AddRange and RemoveRange mutate the enumeration causing System.InvalidOperationException

There is a pull request that someone has implemented that solves this problem for one case. It needs to be done for all implementations, such as MoqDbSetExtensions:

96526ba#diff-7b3254564f11dc162ab9ab6dac35c9dd

Otherwise the only solutions are to replace the Setup's everywhere you call SetupData, or change your system under test to use ToList() so the mock data and the callback mutation are using different containers.

Mitigation of transition to linq to objects

As we know unit testing EF queries actually tests those queries by executing it as Linq to objects that poses some problems with what you must write in your query for test to work and what you do not want to have there because it will unnecessarily complicate the sql query eg:

                    from x in baseQuery
                    join y in baseQuery on x.Id equals y.ParentId into z
                    from q in z.DefaultIfEmpty()
                    select new { x.Name, ParentName = q.Name };

Is perfectly fine sql query that will result in nulls for ParentName in none is found but tests for it will fail with null pointer exception.

What I would like to propose it and Extension point in your library that would allow ExpressionVisitors to be applied for tests. For the example above it would rewrite it to use

                     z.DefaultIfEmpty(new TestsSubject())

just fixing the null pointer issue.
Of course this solution is not perfect but it opens community to figuring out ways to mitigate the issue. Check out my fork with working example at https://github.com/rafalFurman/EntityFramework.Testing

GetEnumerator() mock only returns a single enumerator instance

Line 41 of MockDbSetExtensions.cs:

mock.As<IQueryable<TEntity>>().Setup(m => m.GetEnumerator()).Returns(query.GetEnumerator());

Will only return one instance of IEnumerator, which when used once will need to be reset (resulting in the appearance of an empty DbSet on any subsequent enumeration). This does not match the regular behaviour of DbSet.GetEnumerator(), and causes problems if either your code or your debugging tries to enumerate all the items in the DbSet a second time.

Related StackOverflow discussion: DbSet mock, no results while calling ToList secondly

I believe (but haven't yet tested) changing the line to a method that returns a new enumerator will also fix the problem here:

mock.As<IQueryable<TEntity>>().Setup(m => m.GetEnumerator()).Returns(() => query.GetEnumerator());

Example does not build

I just started using this library (1.1.5) and created a simple test which is basically a copy from the examples.

var data = new List<ConfigSetting> { };

var cfSet = new Mock<DbSet<ConfigSetting>>()
    .Setup(data);

but in the Setup() method I get the build error:

cannot convert from
System.Collections.Generic.List<ConfigSetting> to 
System.Linq.Expressions.Expression<System.Action<System.Data.Entity.DbSet<ConfigSetting>>>

IDbSet.AddOrUpdate() and DbContext.Database.BeginTransaction() issue

Test cases fail if AddOrUpdate extension methods is used. e.g. _context.Patients.AddOrUpdate(patient);

Also if a method is using transactions DbContext.Database.BeginTransaction() then System.Data.Entity.ModelConfiguration.ModelValidationException is thrown.

e.g. using (var transaction = _context.Database.BeginTransaction())
{
//db operations
}

Include not working

Include is not working when used as an Expression.
Here the example code to reproduce the problem:

`public T Get(Expression<Func<T, bool>> predicate, params Expression<Func<T, object>>[] includes)
{
IQueryable query = _set;

        query = query.Where(predicate);

        if (includes != null && includes.Length > 0)
            foreach (var include in includes)
                query = query.Include(include);

        return query.FirstOrDefault();
    }`

Release a new package

With the latest code changes, issues #30 and #31 were fixed. However, no release was created to include these changes.

Could you please create a new package?

EF7

Do you have any plans on developing a version of your awesome library for EF7? We used your EntityFrameworkTesting.NSubstitute a lot in our application and in the process of starting the migration from EF6 to EF7, we hit the wall with all our unit tests using your library with EF7.
Thanks.

NSubstitue 4 support

I got the following error if I upgrade to NSubstitute 4.0 and try to use the sample code to set up a fake dbset.

System.MissingMethodException Method not found: 'System.__Canon NSubstitute.Arg.Any()'. NSubstitute.NSubstituteDbSetExtensions.SetupData[TEntity](DbSet'1 dbSet, ICollection'1 data, Func'2 find)

Note, this is also posted as a question on StackOverflow.

NSubstitute version

I have been trying out EntityFramework.Testing.NSubstitute. It was very easy to get up and running and my tests work great in Visual Studio. The tests however, fail when run on the build server. It appears that EntityFramework.Testing.NSubstitute requires NSubstitute 1.8.1.0. The latest version of NSubstitute is now v1.8.2.0. I have reverted to using the older version of NSubstitute for now but was wondering if there were any plans to upgrade EntityFramework.Testing.NSubstitute to work with the latest version of NSubstitute?

DirectoryNotFoundException when measuring code coverage

I have set of XUnit tests using EntityFramework.Testing package and when I run them using xunit runner everything is OK:

C:\WhateverProject>.\packages\xunit.runner.console.2.2.0\tools\xunit.console.exe ".\WhateverProject.UnitTests\bin\Release\WhateverProject.UnitTests.dll" -xml TestResults.WhateverProject.xml
xUnit.net Console Runner (64-bit .NET 4.0.30319.42000)
Discovering: WhateverProject.UnitTests
Discovered: WhateverProject.UnitTests
Starting: WhateverProject.UnitTests
Finished: WhateverProject.UnitTests
=== TEST EXECUTION SUMMARY ===
WhateverProject.UnitTests Total: 79, Errors: 0, Failed: 0, Skipped: 0, Time: 8.398s

However when I am using OpenCover.Console.exe to execute the tests and measure the coverage, I am getting DirectoryNotFoundException:

C:\WhateverProject>OpenCover.Console.exe -output:".\opencover.xml" -register:user -mergeoutput -target:".\packages\xunit.runner.cons
ole.2.2.0\tools\xunit.console.exe" -targetargs:"WhateverProject.UnitTests.dll" -targetdir:".\WhateverProject.UnitTests\bin\Release"
Loading coverage file C:\WhateverProject.\opencover.xml
Executing: C:\WhateverProject\packages\xunit.runner.console.2.2.0\tools\xunit.console.exe
xUnit.net Console Runner (64-bit .NET 4.0.30319.42000)
Discovering: WhateverProject.UnitTests
Discovered: WhateverProject.UnitTests
Starting: WhateverProject.UnitTests
Finished: WhateverProject.UnitTests
=== TEST EXECUTION SUMMARY ===
WhateverProject.UnitTests Total: 79, Errors: 0, Failed: 0, Skipped: 0, Time: 10.489s
Committing...
An System.IO.DirectoryNotFoundException occured: Could not find a part of the path 'c:\Users\Scott\Documents\GitHub\scott-xu\EntityFramework.Testing\src\EntityFramework.Testing.Moq\MoqDbSetExtensions.cs'.
An System.IO.DirectoryNotFoundException occured: Could not find a part of the path 'c:\Users\Scott\Documents\GitHub\scott-xu\EntityFramework.Testing\src\EntityFramework.Testing\DebugCheck.cs'.
An System.IO.DirectoryNotFoundException occured: Could not find a part of the path 'c:\Users\Scott\Documents\GitHub\scott-xu\EntityFramework.Testing\src\EntityFramework.Testing\InMemoryAsyncQueryable{T}.cs'.
An System.IO.DirectoryNotFoundException occured: Could not find a part of the path 'c:\Users\Scott\Documents\GitHub\scott-xu\EntityFramework.Testing\src\EntityFramework.Testing\InMemoryAsyncQueryProvider.cs'.
An System.IO.DirectoryNotFoundException occured: Could not find a part of the path 'c:\Users\Scott\Documents\GitHub\scott-xu\EntityFramework.Testing\src\EntityFramework.Testing\InMemoryDbAsyncEnumerator{T}.cs'.
An System.IO.DirectoryNotFoundException occured: Could not find a part of the path 'c:\Users\Scott\Documents\GitHub\scott-xu\EntityFramework.Testing\src\EntityFramework.Testing\TypeExtensions.cs'.
An System.IO.DirectoryNotFoundException occured: Could not find a part of the path 'c:\Users\Scott\Documents\GitHub\scott-xu\EntityFramework.Testing\src\EntityFramework.Testing.Moq\MoqDbSetExtensions.cs'.
An System.IO.DirectoryNotFoundException occured: Could not find a part of the path 'c:\Users\Scott\Documents\GitHub\scott-xu\EntityFramework.Testing\src\EntityFramework.Testing\DebugCheck.cs'.
An System.IO.DirectoryNotFoundException occured: Could not find a part of the path 'c:\Users\Scott\Documents\GitHub\scott-xu\EntityFramework.Testing\src\EntityFramework.Testing\InMemoryAsyncQueryable{T}.cs'.
An System.IO.DirectoryNotFoundException occured: Could not find a part of the path 'c:\Users\Scott\Documents\GitHub\scott-xu\EntityFramework.Testing\src\EntityFramework.Testing\InMemoryAsyncQueryProvider.cs'.
An System.IO.DirectoryNotFoundException occured: Could not find a part of the path 'c:\Users\Scott\Documents\GitHub\scott-xu\EntityFramework.Testing\src\EntityFramework.Testing\InMemoryDbAsyncEnumerator{T}.cs'.
An System.IO.DirectoryNotFoundException occured: Could not find a part of the path 'c:\Users\Scott\Documents\GitHub\scott-xu\EntityFramework.Testing\src\EntityFramework.Testing\TypeExtensions.cs'.
An System.IO.DirectoryNotFoundException occured: Could not find a part of the path 'c:\Users\Scott\Documents\GitHub\scott-xu\EntityFramework.Testing\src\EntityFramework.Testing.Moq\MoqDbSetExtensions.cs'.
An System.IO.DirectoryNotFoundException occured: Could not find a part of the path 'c:\Users\Scott\Documents\GitHub\scott-xu\EntityFramework.Testing\src\EntityFramework.Testing\DebugCheck.cs'.
An System.IO.DirectoryNotFoundException occured: Could not find a part of the path 'c:\Users\Scott\Documents\GitHub\scott-xu\EntityFramework.Testing\src\EntityFramework.Testing\InMemoryAsyncQueryable{T}.cs'.
An System.IO.DirectoryNotFoundException occured: Could not find a part of the path 'c:\Users\Scott\Documents\GitHub\scott-xu\EntityFramework.Testing\src\EntityFramework.Testing\InMemoryAsyncQueryProvider.cs'.
An System.IO.DirectoryNotFoundException occured: Could not find a part of the path 'c:\Users\Scott\Documents\GitHub\scott-xu\EntityFramework.Testing\src\EntityFramework.Testing\InMemoryDbAsyncEnumerator{T}.cs'.
An System.IO.DirectoryNotFoundException occured: Could not find a part of the path 'c:\Users\Scott\Documents\GitHub\scott-xu\EntityFramework.Testing\src\EntityFramework.Testing\TypeExtensions.cs'.
Visited Classes 698 of 1722 (40.53)
Visited Methods 1638 of 5005 (32.73)
Visited Points 4722 of 13432 (35.15)
Visited Branches 2029 of 7089 (28.62)

==== Alternative Results (includes all methods including those without corresponding source) ====
Alternative Visited Classes 772 of 2016 (38.29)
Alternative Visited Methods 2545 of 8552 (29.76)

Request support for Entity Framework 6.3 on .netstandard 2.1

An update to EF has been released with .net core 3 to allow a .net framework to .net core migration path.

Please, can we have a release that supports EF 6.3 on .net standard?

A quick look at the code base look like there is a need to update the reflection logic in InMemoryAsyncQueryProvider to handle .net core.

Entry(existingobject).CurrentValues throws exception

I have some code in a repository pattern class like this

var existing = this.Find(id); //find returns an instance of MyClass or null
if(existing!=null){
    this._context.Entry(existing).CurrentValues.SetValues(newvalues);
}

which throws

 Member 'CurrentValues' cannot be called for the entity of type 'MyClass' because the entity does not exist in the context. To add an entity to the context call the Add or Attach method of DbSet<MyClass>

I get the impression from examples that this code should work. I think its failing because the mocked DbContext/Dbsets don't work 100% the same as the actually entity framework implementations. Entry correctly pulls out the DbEntity, but it's not actually in the tracked objects?.

Entity framework is currently the bane of my existence when it comes to testing code :(

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.