Comments (6)
Hi rosdi,
This is the right place to ask since there are no other places for these sort of questions :)
I'm assuming that you followed Microsoft's guidance to create your stub DbContext and DbSet instances.
You'd now like to get DbContextScope
to return these instead of the real instances. This is actually very easy (or I think it is anyway, I haven't actually tried it yet :) )
You'll note that the DbContextScope
constructor takes an optional IDbContextFactory
instance. The IDbContextFactory
was created to do precisely what you're trying to do: it lets you control the creation of the DbContext
instances, allowing you to e.g. substitute them with a stub implementation.
So in your unit test, simply implement the IDbContextFactory
interface and get it to return your stub DbContext
instance. Alternatively, you can of course use a mocking library like Moq to do that for you. Then, provide this "stub DbContext factory" to your DbContextScope
and you're all done.
from dbcontextscope.
Nevermind.. I will just do integration test instead... and this is not even a proper place to ask this question anyway. Sorry about that.
from dbcontextscope.
I had the same question last week for myself. Ended up with this kind of fake. Not fully implemented obviously, but enough for now.
Note: my real services are using AmbientDbContextLocator
, but within unit tests I don't need it, that's why IDbContextCollection DbContexts
is not implemented.
/// <summary>
/// Represents fake DbContextScope for services unit testing
/// </summary>
public class FakeDbContextScope : IDbContextScope
{
private bool _disposed;
private int _saveChangesCount;
public FakeDbContextScope()
{
_disposed = false;
_saveChangesCount = 0;
}
public int SaveChanges()
{
_saveChangesCount++;
return 0;
}
public Task<int> SaveChangesAsync()
{
throw new NotImplementedException("SaveChangesAsync() is not implemented within FakeDbContextScope");
}
public Task<int> SaveChangesAsync(CancellationToken cancelToken)
{
throw new NotImplementedException("SaveChangesAsync(cancelToken) is not implemented within FakeDbContextScope");
}
public void RefreshEntitiesInParentScope(IEnumerable entities)
{
throw new NotImplementedException("RefreshEntitiesInParentScope(entities) is not implemented within FakeDbContextScope");
}
public Task RefreshEntitiesInParentScopeAsync(IEnumerable entities)
{
throw new NotImplementedException("RefreshEntitiesInParentScopeAsync(entities) is not implemented within FakeDbContextScope");
}
public IDbContextCollection DbContexts
{
get
{
throw new NotImplementedException("IDbContextCollection() is not implemented within FakeDbContextScope");
}
}
public bool Disposed
{
get
{
return _disposed;
}
}
public void Dispose()
{
_disposed = true;
}
}
from dbcontextscope.
I got it to work... thanks to both of you.. from now on I don't see any reason NOT to use DbContextScope for my future projects... cheers..
from dbcontextscope.
Hi. I followed the guide you referenced above for creating stub DbContext and DbSet instances but I am still having trouble mocking a service similar(really the exact same) to the 'SendWelcomeEmail' in the UserEmailService examples. I am injecting IDbContextScopeFactory (using autofac) just like the UserEmailService example(no other dependencies) but I can't figure out how to mock the service. I am using moq. Any help would be greatly appreciated. I love the work you have done, it is making all of my projects so much easier. Thanks ahead.
public async Task Test_vendor_async_service()
{
//shortened for brevity
var data = new List<Vendor>();
var mockSet = new Mock<DbSet<Vendor>>();
mockSet.As<IDbAsyncEnumerable<Vendor>>()
.Setup(m => m.GetAsyncEnumerator())
.Returns(new TestDbAsyncEnumerator<Vendor>(data.GetEnumerator()));
mockSet.As<IQueryable<Vendor>>()
.Setup(m => m.Provider)
.Returns(new TestDbAsyncQueryProvider<Vendor>(data.Provider));
mockSet.As<IQueryable<Vendor>>().Setup(m => m.Expression).Returns(data.Expression);
mockSet.As<IQueryable<Vendor>>().Setup(m => m.ElementType).Returns(data.ElementType);
mockSet.As<IQueryable<Vendor>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());
//this is where I am not so sure what needs to be done.
var mockFactory = new Mock<IDbContextScopeFactory>();
mockFactory.As<MyContext>()
.Setup(c => c.Vendors).Returns(mockSet.Object);
//I can't really pass in the mockfactory because it of type Mock<T>
//confused
var service = new VendorsService(mockFactory);
var vendors = await service.GetAllAsync().ConfigureAwait(false);
Assert.AreEqual(3, vendors.Count);
Assert.AreEqual("AAA", vendors[0].BusinessName);
Assert.AreEqual("BBB", vendors[1].BusinessName);
Assert.AreEqual("ZZZ", vendors[2].BusinessName);
}
from dbcontextscope.
Hi, I've been working around the DbContextScope which is working fine however when it comes to Unit Testing I have to say I am a bit confused about how I should use the libraries in order to unit test a MVC application.
I am trying to call the method GetScanDefinitions() and assert the objects retrieved with my predefined mockset.
This is my Unit Test class:
public class UnitScanDefinitionsControllerTest
{
private CrawlerContext _dbEntities;
private readonly ICrawlerRepository _crawlerRepository;
private IScanDefinitionService _scanDefinitionService;
public UnitScanDefinitionsControllerTest()
{
IAmbientDbContextLocator ambientDbContextLocator = new AmbientDbContextLocator();
_crawlerRepository = new CrawlerRepository(ambientDbContextLocator);
}
[Fact]
public async Task ScanDefinitionView()
{
var data = new List<ScanDefinition>
{
new ScanDefinition { Name = "AAA" },
new ScanDefinition { Name = "BBB" },
new ScanDefinition { Name = "CCC" },
}.AsQueryable();
var mockSet = new Mock<DbSet<ScanDefinition>>();
mockSet.As<IDbAsyncEnumerable<ScanDefinition>>()
.Setup(m => m.GetAsyncEnumerator())
.Returns(new DbAsyncEnumerator<ScanDefinition>(data.GetEnumerator()));
mockSet.As<IQueryable<ScanDefinition>>()
.Setup(m => m.Provider)
.Returns(new DbAsyncQueryProvider<ScanDefinition>(data.Provider));
mockSet.As<IQueryable<ScanDefinition>>().Setup(m => m.Expression).Returns(data.Expression);
mockSet.As<IQueryable<ScanDefinition>>().Setup(m => m.ElementType).Returns(data.ElementType);
mockSet.As<IQueryable<ScanDefinition>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());
var mockFactory = new Mock<IDbContextFactory>();
mockFactory.Setup(c => c.CreateDbContext<CrawlerContext>()).Returns(_dbEntities);
_dbContextFactory = mockFactory.Object;
// Setup DbContextScopeFactory to use mocked context
_mockContextScope = new DbContextScopeFactory(_dbContextFactory);
_scanDefinitionService = new ScanDefinitionService(_mockContextScope, _crawlerRepository);
var scanDefinitions = await _scanDefinitionService.GetScanDefinitions().ToListAsync();
Assert.Equal(3, scanDefinitions.Count);
Assert.Equal("AAA", scanDefinitions[0].Name);
Assert.Equal("BBB", scanDefinitions[1].Name);
Assert.Equal("ZZZ", scanDefinitions[2].Name);
}
}
The Service Layer looks like this:
public class ScanDefinitionService : IScanDefinitionService
{
private readonly IDbContextScopeFactory _dbContextScopeFactory;
private readonly ICrawlerRepository _crawlerRepository;
public ScanDefinitionService(IDbContextScopeFactory dbContextScopeFactory, ICrawlerRepository context)
{
_dbContextScopeFactory = dbContextScopeFactory;
_crawlerRepository = context;
}
public IQueryable<ScanDefinition> GetScanDefinitions()
{
using (_dbContextScopeFactory.CreateReadOnly())
{
return _crawlerRepository.GetScanDefinitions();
}
}
}
And finally the Repository Layer:
public class CrawlerRepository : ICrawlerRepository
{
private readonly IAmbientDbContextLocator _ambientDbContextLocator;
private CrawlerContext DbContext
{
get
{
var dbContext = _ambientDbContextLocator.Get<CrawlerContext>();
if (dbContext == null)
throw new InvalidOperationException("Db Context Error message");
return dbContext;
}
}
public CrawlerRepository(IAmbientDbContextLocator ambientDbContextLocator)
{
if (ambientDbContextLocator == null) throw new ArgumentNullException("ambientDbContextLocator");
_ambientDbContextLocator = ambientDbContextLocator;
}
public IQueryable<ScanDefinition> GetScanDefinitions()
{
return DbContext.ScanDefinitions **<--- TEST FAILS HERE; Message: System.NullReferenceException : Object reference not set to an instance of an object.**
.Include(sd => sd.ScanBases)
.Include(sd => sd.ScanDefinitionFileTypes)
.Include(sd => sd.ScanDefinitionRuleDefinitions);
}
}
Any help would be much appreciated.
from dbcontextscope.
Related Issues (20)
- Compatibility with Effort
- Use with EntityFramework Reverse POCO Code First Generator? HOT 1
- nested IDbContextFactory.CreateWithTransaction HOT 1
- Need way to disable disposing of DbContext when root DbContextScope is disposed HOT 3
- .net core HOT 2
- Unable to use a non-interfaced DbContext with DbContextScope HOT 2
- TDD with DbContextScope HOT 1
- Connect to database with a different user/connection string HOT 5
- Moving to .Net Standard 2.0 & EF 2.0 HOT 8
- Best practice for taking advantage of EF first-level caching in Domain Service Layer. HOT 5
- Working with Store Procedure and Transaction
- DbContextScope with EF Core !! HOT 6
- Dead link
- Problems when attaching new dbcontexts while performing savechanges
- The current type, EntityFramework.DbContextScope.Interfaces.IDbContextFactory, is an interface and cannot be constructed. Are you missing a type mapping?
- Suggestions: how to retrieve ID generated by DB after saveChanges() HOT 2
- how to use DbContextScope with Parallel.ForEach
- Satellite class to use the same Factory/Locator across application modules
- What to pass to IDbContextFactory argument in DbContextScope constructor? HOT 1
- Support of ASP.NET Core dependency injection out of the box
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dbcontextscope.