4

I have an Entity Framework DB Context file. I am trying to setup a Moq framework in NUnit. Currently receiving error below for Moq Nunit test. How would I setup the DBContext, and add items to a Product Table?

"No database provider has been configured for this DbContext. A provider can be configured by overriding the DbContext.OnConfiguring method or by using AddDbContext on the application service provider. If AddDbContext is used, then also ensure that your DbContext type accepts a DbContextOptions object in its constructor and passes it to the base constructor for DbContext."

Electronics DB Context file

public partial class ElectronicsContext : DbContext
{
    public ElectronicsContext()
    {
    }

    public ElectronicsContext(DbContextOptions<ElectronicsContext> options)
        : base(options)
    {
    }

    public virtual DbSet<Product> Product { get; set; }
    public virtual DbSet<ProductCategory> ProductCategory { get; set; }

Startup.cs

    var connection = @"Server=localhost;Database=Electronics;Trusted_Connection=True;ConnectRetryCount=0";
    services.AddDbContext<ElectronicsContext>(options => options.UseSqlServer(connection));

Moq Nunit Test

 [SetUp]
 public void Setup()
 {
    var ElectronicsContext = new Mock<ElectronicsContext>();
    var ProductRepository = new Mock<ProductRepository>();

    Product producttest = new Product();
    _dbContext.Product.Add(new Product {ProductId = 1, ProductName = "TV", ProductDescription = "TV testing",ImageLocation = "test"});
    _dbContext.SaveChanges();
  • this should help you out: https://mirkomaggioni.com/2017/08/30/ef-db-context-mock-with-moq/ – jazb Oct 15 '18 at 05:20

1 Answers1

18

You don't need to mock the context in unit tests. You should use the DbContextOptions class to specify you want to use an in memory database to run your tests against.

[TestMethod]
public void TestProducts()
{
    var options = new DbContextOptionsBuilder<ElectronicsContext>()
        .UseInMemoryDatabase(databaseName: "Products Test")
        .Options;

    using(var context = new ElectronicsContext(options))
    {
        context.Products.Add(new Product {ProductId = 1, ProductName = "TV", ProductDescription = "TV testing",ImageLocation = "test"});
        context.SaveChanges();
    }

    using(var context = new ElectronicsContext(options))
    {
        // run your test here

    }
}

This runs against the in-memory representation of your database instead of relying on the physical server. The connection string you provided in the startup.cs is not used as part of the tests.

More info can be found here

Simply Ged
  • 8,250
  • 11
  • 32
  • 40
  • 1
    You don't want to do that because the in-memory database will persist for all of your tests. If you read the link I gave you, there is a line that states `Each test method specifies a unique database name, meaning each method has its own InMemory database.` Best practice is to use the test method name as the database name for each test – Simply Ged Oct 15 '18 at 05:41
  • quick question, when should I use Moq then for db testing? –  Oct 31 '18 at 06:32
  • If you can do all your tests using the InMemoryDatabase then you probably don't need Moq for the db testing, but it depends on your architecture. – Simply Ged Oct 31 '18 at 23:49
  • yeah, I Just wanted to know for the sake of it –  Nov 01 '18 at 01:11
  • One of the main benefits of mocking instead of InMemory is the ability to guarantee that an Exception will be thrown. – krillgar Dec 23 '20 at 14:04