Testing is an important part of any application since it tells the developers that their application works correctly. In this tutorial we are going to learn the different techniques to employ in order to test Entity Framework Core codes. These techniques are broadly divided into testing with production database or without the production database. These are:
Page Contents
To understand the process of testing Entity Framework Core codes we will create an example app in ASP.NET Core MVC which depicts the working of a news agency. Start by creating a new ASP.NET Core MVC app and name it EFCoreTesting.
To the app install the following NuGet packages.
All these packages will be used during the course of this tutorial.
Next, add 2 Entity Classes, preferably inside the “Models” folder, which are shown below.
public class News
{
public int Id { get; set; }
public string Name { get; set; }
public string Url { get; set; }
}
public class UrlResource
{
public string Url { get; set; }
}
Next, add Dbcontext, preferably inside the “Models” folder, which is given below.
public class NewsContext : DbContext
{
private readonly Action<NewsContext, ModelBuilder> _modelCustomizer;
#region Constructors
public NewsContext()
{
}
public NewsContext(DbContextOptions<NewsContext> options, Action<NewsContext, ModelBuilder> modelCustomizer = null)
: base(options)
{
_modelCustomizer = modelCustomizer;
}
#endregion
public DbSet<News> News => Set<News>();
public DbSet<UrlResource> UrlResources => Set<UrlResource>();
#region OnConfiguring
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
}
}
#endregion
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<UrlResource>().HasNoKey()
.ToView("AllResources");
if (_modelCustomizer is not null)
{
_modelCustomizer(this, modelBuilder);
}
}
}
The app is ready so we move to the testing part.
The main hurdle with testing against the production database is to ensure proper test isolation, so that tests don’t interfere with each other. This will be discussed on the test cases. Note that we will be using xUnit testing package to write the tests.
Note that we should ensure database is created and seeded exactly once. For this we use xUnit class fixture feature. This ensures that the fixture instance will be created before any of the tests have run, and once all the tests have finished, it will clean up the fixture object by calling Dispose, if present.
Define a TestDatabaseFixture.cs class in your project with the following code. Here we defined the connection string to the database. When the fixture is instantiated, in the constructor it uses EnsureDeleted() to drop the database and then EnsureCreated() to create it with your latest configuration. Once the database is created, it seeds it with some data for the tests to use them.
public class TestDatabaseFixture
{
private const string ConnectionString = @"Server=(localdb)\mssqllocaldb;Database=NewsAgency;Trusted_Connection=True;ConnectRetryCount=0";
private static readonly object _lock = new();
private static bool _databaseInitialized;
public TestDatabaseFixture()
{
lock (_lock)
{
if (!_databaseInitialized)
{
using (var context = CreateContext())
{
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
context.AddRange(
new News { Name = "Donald Trump wins 2025 USA Presidential Election", Url = "https://newsabc.com/usa-2025-donald-trump/" },
new News { Name = "Elon Musk worth soared to $1 trillion", Url = "https://newsabc.com/elon-musk-trillionaire/" });
context.SaveChanges();
}
_databaseInitialized = true;
}
}
}
public NewsContext CreateContext()
=> new NewsContext(
new DbContextOptionsBuilder<NewsContext>()
.UseSqlServer(ConnectionString)
.Options);
}
There is a locking feature in the fixture’s creation logic above. This ensures that the database creation and seeding are done exactly once for all the tests.
In the controller there are method to get news, get all news, add a new and update news url. The controller code is given below.
[ApiController]
[Route("[controller]")]
public class NewsController : ControllerBase
{
private readonly NewsContext _context;
public NewsController(NewsContext context)
=> _context = context;
[HttpGet]
public async Task<ActionResult<News>> GetNews(string name)
{
var news = await _context.News.FirstOrDefaultAsync(b => b.Name == name);
return news is null ? NotFound() : news;
}
[HttpGet]
[Route("GetAllNews")]
public IAsyncEnumerable<News> GetAllNews()
=> _context.News.OrderBy(b => b.Name).AsAsyncEnumerable();
[HttpPost]
public async Task<ActionResult> AddNews(string name, string url)
{
_context.News.Add(new News { Name = name, Url = url });
await _context.SaveChangesAsync();
return Ok();
}
[HttpPost]
public async Task<ActionResult> UpdateNewsUrl(string name, string url)
{
// Note: it isn't usually necessary to start a transaction for updating. This is done here for illustration purposes only.
await using var transaction = await _context.Database.BeginTransactionAsync(IsolationLevel.Serializable);
var news = await _context.News.FirstOrDefaultAsync(b => b.Name == name);
if (news is null)
{
return NotFound();
}
news.Url = url;
await _context.SaveChangesAsync();
await transaction.CommitAsync();
return Ok();
}
}
We are now going to test these methods.
In the app create a new folder called Tests, in this folder we will create our test class files. So first add a new class file called NewsControllerTest.cs, to this file add the following tests.
public class NewsControllerTest : IClassFixture<TestDatabaseFixture>
{
public NewsControllerTest(TestDatabaseFixture fixture)
=> Fixture = fixture;
public TestDatabaseFixture Fixture { get; }
[Fact]
public async Task GetNews()
{
using var context = Fixture.CreateContext();
var controller = new NewsController(context);
var news = (await controller.GetNews("Elon Musk worth soared to $1 trillion")).Value;
Assert.Equal("https://newsabc.com/elon-musk-trillionaire/", news.Url);
}
[Fact]
public async Task GetAllNews()
{
using var context = Fixture.CreateContext();
var controller = new NewsController(context);
var news = await controller.GetAllNews().ToListAsync();
Assert.Collection(
news,
b => Assert.Equal("Donald Trump wins 2025 USA Presidential Election", b.Name),
b => Assert.Equal("Elon Musk worth soared to $1 trillion", b.Name));
}
[Fact]
public async Task AddNews()
{
using var context = Fixture.CreateContext();
context.Database.BeginTransaction();
var controller = new NewsController(context);
await controller.AddNews("Bitcoin set to reach $1 million", "https://newsabc.com/btc-one-million/");
context.ChangeTracker.Clear();
var news = await context.News.SingleAsync(b => b.Name == "Bitcoin set to reach $1 million");
Assert.Equal("https://newsabc.com/btc-one-million/", news.Url);
}
}
Explanation: To use the fixture in a test class, we implement IClassFixture<TestDatabaseFixture>, then xUnit will inject it into the constructor.
public class NewsControllerTest : IClassFixture<TestDatabaseFixture>
{
public NewsControllerTest(TestDatabaseFixture fixture)
=> Fixture = fixture;
public TestDatabaseFixture Fixture { get; }
}
We now have Fixture property to create the context.
using var context = Fixture.CreateContext();
See the test methods GetNews() and GetAllNews() where we are using the fixture property to create the DbContext and then testing the returned records data with Assert.Equal() method.
[Fact]
public async Task GetNews()
{
using var context = Fixture.CreateContext();
var controller = new NewsController(context);
var news = (await controller.GetNews("Elon Musk worth soared to $1 trillion")).Value;
Assert.Equal("https://newsabc.com/elon-musk-trillionaire/", news.Url);
}
[Fact]
public async Task GetAllNews()
{
using var context = Fixture.CreateContext();
var controller = new NewsController(context);
var news = await controller.GetAllNews().ToListAsync();
Assert.Collection(
news,
b => Assert.Equal("Donald Trump wins 2025 USA Presidential Election", b.Name),
b => Assert.Equal("Elon Musk worth soared to $1 trillion", b.Name));
}
Note that the above 2 test methods are just a read only process where no database updating is required. We also have a test method where database is inserted with new news. Tests where data modification happens tends to written differently since they may interfere with one another. These test needs to be done in isolation. See the AddNews() test method where we used transaction.
[Fact]
public async Task AddNews()
{
using var context = Fixture.CreateContext();
context.Database.BeginTransaction();
var controller = new NewsController(context);
await controller.AddNews("Bitcoin set to reach $1 million", "https://newsabc.com/btc-one-million/");
context.ChangeTracker.Clear();
var news = await context.News.SingleAsync(b => b.Name == "Bitcoin set to reach $1 million");
Assert.Equal("https://newsabc.com/btc-one-million/", news.Url);
}
The transaction is never committed and it is rolled back at the end of the test. So no database changes happens and this make the test don’t interfere with other tests. When the database updates are made the change tracker is cleared with context.ChangeTracker.Clear(), to make sure we actually load the news from the database.
The UpdateNewsUrl() method of the News Controller which modify data and also explicitly manage transactions. As the databases do not typically support nested transactions, it isn’t possible to use transactions for isolation as we did in the above test above.
[HttpPost]
public async Task<ActionResult> UpdateNewsUrl(string name, string url)
{
// Note: it isn't usually necessary to start a transaction for updating. This is done here for illustration purposes only.
await using var transaction = await _context.Database.BeginTransactionAsync(IsolationLevel.Serializable);
var news = await _context.News.FirstOrDefaultAsync(b => b.Name == name);
if (news is null)
{
return NotFound();
}
news.Url = url;
await _context.SaveChangesAsync();
await transaction.CommitAsync();
return Ok();
}
In such tests we must clean up the database to its original state after each test, and parallelization must be disabled so that these tests don’t interfere with each other. Here we define another fixture with separate database, to make sure it don’t interfere with the other tests.
So, to the Tests folder add a new class called TransactionalTestDatabaseFixture.cs with the following code.
public class TransactionalTestDatabaseFixture
{
private const string ConnectionString = @"Server=(localdb)\mssqllocaldb;Database=NewsAgency;Trusted_Connection=True;ConnectRetryCount=0";
public NewsContext CreateContext()
=> new NewsContext(
new DbContextOptionsBuilder<NewsContext>()
.UseSqlServer(ConnectionString)
.Options);
public TransactionalTestDatabaseFixture()
{
using var context = CreateContext();
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
Cleanup();
}
public void Cleanup()
{
using var context = CreateContext();
context.News.RemoveRange(context.News);
context.AddRange(
new News { Name = "Donald Trump wins 2025 USA Presidential Election", Url = "https://newsabc.com/usa-2025-donald-trump/" },
new News { Name = "Elon Musk worth soared to $1 trillion", Url = "https://newsabc.com/elon-musk-trillionaire/" });
context.SaveChanges();
}
}
[CollectionDefinition("TransactionalTests")]
public class TransactionalTestsCollection : ICollectionFixture<TransactionalTestDatabaseFixture>
{
}
In this fixture the Cleanup method is called after every test to ensure that the database is reset to its starting state. We want to share this fixture between multiple classes, so we don’t need these classes run in parallel, to avoid any interference. To do that, we will use this as an xUnit collection fixture rather than as a class fixture. We define a test collection, which references the fixture and will be used by all transactional test classes which require it. The code is:
[CollectionDefinition("TransactionalTests")]
public class TransactionalTestsCollection : ICollectionFixture<TransactionalTestDatabaseFixture>
{
}
Now to the “Tests” folder add a new class called TransactionalNewsControllerTest.cs where we write the test method.
[Collection("TransactionalTests")]
public class TransactionalNewsControllerTest: IDisposable
{
public TransactionalNewsControllerTest(TransactionalTestDatabaseFixture fixture)
=> Fixture = fixture;
public TransactionalTestDatabaseFixture Fixture { get; }
[Fact]
public async Task UpdateNewsUrl()
{
using (var context = Fixture.CreateContext())
{
var controller = new NewsController(context);
await controller.UpdateNewsUrl("Elon Musk worth soared to $1 trillion", "https://newsabc.com/elon-musk-trillionaire-news-updated/");
}
using (var context = Fixture.CreateContext())
{
var news = await context.News.SingleAsync(b => b.Name == "Elon Musk worth soared to $1 trillion");
Assert.Equal("https://newsabc.com/elon-musk-trillionaire-news-updated/", news.Url);
}
}
public void Dispose()
=> Fixture.Cleanup();
}
Note that xUnit doesn’t parallelize tests within the same class. If we want to share this fixture between multiple classes, we must make sure these classes don’t run in parallel, to avoid any interference. To do that, we will use this as an xUnit collection fixture (notice the attribute [Collection(“TransactionalTests”)] ) rather than as a class fixture. To do this we define a test collection, which references our fixture and will be used by all transactional test classes which require it.
Now xUnit instantiates the collection fixture once, there is no need for us to use locking around database creation and seeding as before.
When you have decided to perform testing without using the Production Database then you can find the following approaches:
In the Repository Pattern we put all the EF Core LINQ queries to a separate layer which is known as Repository. This Repository later is used for creating simulated objects (mocks) that mimic real dependencies (like databases, APIs, or other classes) to test a component in isolation.
Start by adding an interface called INewsRepository.cs to the Models folder with the following code.
public interface INewsRepository
{
Task<News> GetNewsByNameAsync(string name);
IAsyncEnumerable<News> GetAllNewsAsync();
void AddNews(News news);
Task SaveChangesAsync();
}
Next, implement the interface in a class called NewsRepository.cs. The code is given below.
public class NewsRepository : INewsRepository
{
private readonly NewsContext _context;
public NewsRepository(NewsContext context)
=> _context = context;
public async Task<News> GetNewsByNameAsync(string name)
=> await _context.News.FirstOrDefaultAsync(b => b.Name == name);
public IAsyncEnumerable<News> GetAllNewsAsync()
=> _context.News.AsAsyncEnumerable();
public void AddNews(News news)
=> _context.Add(news);
public async Task SaveChangesAsync()
=> await _context.SaveChangesAsync();
}
The repository has methods to execute LINQ queries on the database which allows us to easily mock these repository methods.
We need to register the repository as a service in dependency injection by adding the following to the application’s Program class.
builder.Services.AddScoped<INewsRepository, NewsRepository>();
With this setup the controllers get injected with the repository service instead of the EF Core context. Now add a new controller called NewsControllerWithRepository.cs where methods interacts with the database using repository. The code is given below.
[ApiController]
[Route("[controller]")]
public class NewsControllerWithRepository : ControllerBase
{
private readonly INewsRepository _repository;
public NewsControllerWithRepository(INewsRepository repository)
=> _repository = repository;
[HttpGet]
public async Task<News> GetNews(string name)
=> await _repository.GetNewsByNameAsync(name);
[HttpGet]
public IAsyncEnumerable<News> GetAllNews()
=> _repository.GetAllNewsAsync();
[HttpPost]
public async Task AddNews(string name, string url)
{
_repository.AddNews(new News { Name = name, Url = url });
await _repository.SaveChangesAsync();
}
[HttpPost]
public async Task<ActionResult> UpdateNewsUrl(string name, string url)
{
var news = await _repository.GetNewsByNameAsync(name);
if (news is null)
{
return NotFound();
}
news.Url = url;
await _repository.SaveChangesAsync();
return Ok();
}
}
Now the contact with the data access layer i.e. EF Core is via the repository layer which acts as a mediator between application code and actual database queries. Tests can now be written simply by stubbing out the repository, or by mocking it with your favorite MOQ library. Recall the MOQ package was already installed to the app.
Add RepositoryNewsControllerTest.cs to the “Tests” folder. It’s code is given below.
public class RepositoryNewsControllerTest
{
[Fact]
public async Task GetNews()
{
// Arrange
var repositoryMock = new Mock<INewsRepository>();
repositoryMock
.Setup(r => r.GetNewsByNameAsync("Elon Musk worth soared to $1 trillion"))
.Returns(Task.FromResult(new News { Name = "Elon Musk worth soared to $1 trillion", Url = "https://newsabc.com/elon-musk-trillionaire/" }));
var controller = new NewsControllerWithRepository(repositoryMock.Object);
// Act
var news = await controller.GetNews("Elon Musk worth soared to $1 trillion");
// Assert
repositoryMock.Verify(r => r.GetNewsByNameAsync("Elon Musk worth soared to $1 trillion"));
Assert.Equal("https://newsabc.com/elon-musk-trillionaire/", news.Url);
}
[Fact]
public async Task GetAllNews()
{
// Arrange
var repositoryMock = new Mock<INewsRepository>();
repositoryMock
.Setup(r => r.GetAllNewsAsync())
.Returns(new[]
{
new News { Name = "Donald Trump wins 2025 USA Presidential Election", Url = "https://newsabc.com/usa-2025-donald-trump/" },
new News { Name = "Elon Musk worth soared to $1 trillion", Url = "https://newsabc.com/elon-musk-trillionaire/" }
}.ToAsyncEnumerable());
var controller = new NewsControllerWithRepository(repositoryMock.Object);
// Act
var news = await controller.GetAllNews().ToListAsync();
// Assert
repositoryMock.Verify(r => r.GetAllNewsAsync());
Assert.Equal("https://newsabc.com/usa-2025-donald-trump/", news[0].Url);
Assert.Equal("https://newsabc.com/elon-musk-trillionaire/", news[1].Url);
}
[Fact]
public async Task AddNews()
{
// Arrange
var repositoryMock = new Mock<INewsRepository>();
var controller = new NewsControllerWithRepository(repositoryMock.Object);
// Act
await controller.AddNews("Elon Musk worth soared to $1 trillion", "https://newsabc.com/elon-musk-trillionaire/");
// Assert
repositoryMock.Verify(r => r.AddNews(It.IsAny<News>()));
repositoryMock.Verify(r => r.SaveChangesAsync());
}
[Fact]
public async Task UpdateNewsUrl()
{
var news = new News { Name = "Elon Musk worth soared to $1 trillion", Url = "https://newsabc.com/elon-musk-trillionaire/" };
// Arrange
var repositoryMock = new Mock<INewsRepository>();
repositoryMock
.Setup(r => r.GetNewsByNameAsync("Elon Musk worth soared to $1 trillion"))
.Returns(Task.FromResult(news));
var controller = new NewsControllerWithRepository(repositoryMock.Object);
// Act
await controller.UpdateNewsUrl("Elon Musk worth soared to $1 trillion", "https://newsabc.com/elon-musk-trillionaire-news-updated/");
// Assert
repositoryMock.Verify(r => r.GetNewsByNameAsync("Elon Musk worth soared to $1 trillion"));
repositoryMock.Verify(r => r.SaveChangesAsync());
Assert.Equal("https://newsabc.com/elon-musk-trillionaire-news-updated/", news.Url);
}
}
In the above MOQ code we first create a MOQ object.
var repositoryMock = new Mock<INewsRepository>();
Then do some setup to it which tells what to return when a method of the repository is called.
repositoryMock
.Setup(r => r.GetNewsByNameAsync("Elon Musk worth soared to $1 trillion"))
.Returns(Task.FromResult(new News { Name = "Elon Musk worth soared to $1 trillion", Url = "https://newsabc.com/elon-musk-trillionaire/" }));
Finally, after calling the repository method we do the assertions.
repositoryMock.Verify(r => r.GetNewsByNameAsync("Elon Musk worth soared to $1 trillion"));
Assert.Equal("https://newsabc.com/elon-musk-trillionaire/", news.Url);
Instead of your production database we can use SQLite in-memory database for testing. Since it is based on memory so there are no SQLite files involved.
By default, in SQLite in-memory, a new database is created whenever a connection is opened, and that it’s deleted when that connection is closed. This would lead to resetting the database every time and is a problem so we will open a connection before passing it to EF Core, and arrange for it to be closed only when the test completes. This method will solve the problem.
Add SqliteInMemoryNewsControllerTest.cs to the “Tests” folder. It’s code is given below.
public class SqliteInMemoryNewsControllerTest : IDisposable
{
private readonly DbConnection _connection;
private readonly DbContextOptions<NewsContext> _contextOptions;
public SqliteInMemoryNewsControllerTest()
{
// Create and open a connection. This creates the SQLite in-memory database, which will persist until the connection is closed
// at the end of the test (see Dispose below).
_connection = new SqliteConnection("Filename=:memory:");
_connection.Open();
// These options will be used by the context instances in this test suite, including the connection opened above.
_contextOptions = new DbContextOptionsBuilder<NewsContext>()
.UseSqlite(_connection)
.Options;
// Create the schema and seed some data
using var context = new NewsContext(_contextOptions);
if (context.Database.EnsureCreated())
{
using var viewCommand = context.Database.GetDbConnection().CreateCommand();
viewCommand.CommandText = @"
CREATE VIEW AllResources AS
SELECT Url
FROM News;";
viewCommand.ExecuteNonQuery();
}
context.AddRange(
new News { Name = "Donald Trump wins 2025 USA Presidential Election", Url = "https://newsabc.com/usa-2025-donald-trump/" },
new News { Name = "Elon Musk worth soared to $1 trillion", Url = "https://newsabc.com/elon-musk-trillionaire/" });
context.SaveChanges();
}
NewsContext CreateContext() => new NewsContext(_contextOptions);
public void Dispose() => _connection.Dispose();
[Fact]
public async Task GetNews()
{
using var context = CreateContext();
var controller = new NewsController(context);
var news = (await controller.GetNews("Elon Musk worth soared to $1 trillion")).Value;
Assert.Equal("https://newsabc.com/elon-musk-trillionaire/", news.Url);
}
[Fact]
public async Task GetAllNews()
{
using var context = CreateContext();
var controller = new NewsController(context);
var news = await controller.GetAllNews().ToListAsync();
Assert.Collection(
news,
b => Assert.Equal("Donald Trump wins 2025 USA Presidential Election", b.Name),
b => Assert.Equal("Elon Musk worth soared to $1 trillion", b.Name));
}
[Fact]
public async Task AddNews()
{
using var context = CreateContext();
var controller = new NewsController(context);
await controller.AddNews("Bitcoin set to reach $1 million", "https://newsabc.com/btc-one-million/");
var news = await context.News.SingleAsync(b => b.Name == "Bitcoin set to reach $1 million");
Assert.Equal("https://newsabc.com/btc-one-million/", news.Url);
}
[Fact]
public async Task UpdateNewsUrl()
{
using var context = CreateContext();
var controller = new NewsController(context);
await controller.UpdateNewsUrl("Elon Musk worth soared to $1 trillion", "https://newsabc.com/elon-musk-trillionaire-news-updated/");
var news = await context.News.SingleAsync(b => b.Name == "Elon Musk worth soared to $1 trillion");
Assert.Equal("https://newsabc.com/elon-musk-trillionaire-news-updated/", news.Url);
}
}
Tests call CreateContext() method which returns a context for SQLite In-Memory database and having a clean database with the seeded data.
In the In-memory provider the test class constructor sets up and seeds a new in-memory database before each test. To the “Tests” folder add the InMemoryNewsControllerTest.cs file with the following code.
public class InMemoryNewsControllerTest
{
private readonly DbContextOptions<NewsContext> _contextOptions;
public InMemoryNewsControllerTest()
{
_contextOptions = new DbContextOptionsBuilder<NewsContext>()
.UseInMemoryDatabase("NewsControllerTest")
.ConfigureWarnings(b => b.Ignore(InMemoryEventId.TransactionIgnoredWarning))
.Options;
using var context = new NewsContext(_contextOptions);
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
context.AddRange(
new News { Name = "Donald Trump wins 2025 USA Presidential Election", Url = "https://newsabc.com/usa-2025-donald-trump/" },
new News { Name = "Elon Musk worth soared to $1 trillion", Url = "https://newsabc.com/elon-musk-trillionaire/" });
context.SaveChanges();
}
[Fact]
public async Task GetNews()
{
using var context = CreateContext();
var controller = new NewsController(context);
var news = (await controller.GetNews("Elon Musk worth soared to $1 trillion")).Value;
Assert.Equal("https://newsabc.com/elon-musk-trillionaire/", news.Url);
}
[Fact]
public async Task GetAllNews()
{
using var context = CreateContext();
var controller = new NewsController(context);
var news = await controller.GetAllNews().ToListAsync();
Assert.Collection(
news,
b => Assert.Equal("Donald Trump wins 2025 USA Presidential Election", b.Name),
b => Assert.Equal("Elon Musk worth soared to $1 trillion", b.Name));
}
[Fact]
public async Task AddNews()
{
using var context = CreateContext();
var controller = new NewsController(context);
await controller.AddNews("Bitcoin set to reach $1 million", "https://newsabc.com/btc-one-million/");
var news = await context.News.SingleAsync(b => b.Name == "Bitcoin set to reach $1 million");
Assert.Equal("https://newsabc.com/btc-one-million/", news.Url);
}
[Fact]
public async Task UpdateNewsUrl()
{
using var context = CreateContext();
var controller = new NewsController(context);
await controller.UpdateNewsUrl("Elon Musk worth soared to $1 trillion", "https://newsabc.com/elon-musk-trillionaire-news-updated/");
var news = await context.News.SingleAsync(b => b.Name == "Elon Musk worth soared to $1 trillion");
Assert.Equal("https://newsabc.com/elon-musk-trillionaire-news-updated/", news.Url);
}
NewsContext CreateContext() => new NewsContext(_contextOptions, (context, modelBuilder) =>
{
modelBuilder.Entity<UrlResource>()
.ToInMemoryQuery(() => context.News.Select(b => new UrlResource { Url = b.Url }));
});
}
In this tutorial we learned all about the Entity Framework Core testing procedures involving the production database and also when production database is not involved. We also learned to use Repository patterns for Mocking EF Core and SQLite and In-Memory methods to perform testing.