Skip to content

Commit 2e06ca9

Browse files
committed
Fix RuntimeMigration tests by skipping table creation in test store
Migration tests need to start with an empty database (no tables) so they can test creating and applying migrations from scratch. The default test stores call EnsureCreatedResilientlyAsync() which creates all tables, causing "table already exists" errors when tests try to run migrations. This fix creates custom test store factories that: - SQLite: Uses SqliteTestStore.GetExisting() which sets seed=false - SQL Server: Creates a custom SqlServerTestStore subclass that overrides InitializeAsync to skip table creation Each test still calls CleanDatabase() to drop any existing tables before running, ensuring a clean state for each test.
1 parent a34e480 commit 2e06ca9

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

test/EFCore.SqlServer.FunctionalTests/RuntimeMigrationSqlServerTest.cs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System.Data.Common;
55
using Microsoft.EntityFrameworkCore.SqlServer.Design.Internal;
6+
using Microsoft.EntityFrameworkCore.TestUtilities;
67

78
namespace Microsoft.EntityFrameworkCore;
89

@@ -60,7 +61,7 @@ FROM sys.foreign_keys f
6061
public class RuntimeMigrationSqlServerFixture : RuntimeMigrationFixtureBase
6162
{
6263
protected override ITestStoreFactory TestStoreFactory
63-
=> SqlServerTestStoreFactory.Instance;
64+
=> RuntimeMigrationSqlServerTestStoreFactory.Instance;
6465

6566
protected override List<string> GetTableNames(DbConnection connection)
6667
{
@@ -75,4 +76,44 @@ protected override List<string> GetTableNames(DbConnection connection)
7576
return tables;
7677
}
7778
}
79+
80+
/// <summary>
81+
/// Custom test store factory for RuntimeMigration tests that creates an empty database
82+
/// without seeding (creating tables). This is necessary because migration tests need
83+
/// to start with an empty database to test creating and applying migrations from scratch.
84+
/// </summary>
85+
private class RuntimeMigrationSqlServerTestStoreFactory : SqlServerTestStoreFactory
86+
{
87+
public static new RuntimeMigrationSqlServerTestStoreFactory Instance { get; } = new();
88+
89+
private RuntimeMigrationSqlServerTestStoreFactory()
90+
{
91+
}
92+
93+
public override TestStore GetOrCreate(string storeName)
94+
=> new RuntimeMigrationSqlServerTestStore(storeName);
95+
}
96+
97+
/// <summary>
98+
/// A SqlServerTestStore subclass that skips seeding the database with tables.
99+
/// The InitializeAsync override creates the database but doesn't call EnsureCreated.
100+
/// </summary>
101+
private class RuntimeMigrationSqlServerTestStore : SqlServerTestStore
102+
{
103+
public RuntimeMigrationSqlServerTestStore(string name)
104+
: base(name)
105+
{
106+
}
107+
108+
protected override Task InitializeAsync(
109+
Func<DbContext> createContext,
110+
Func<DbContext, Task> seed,
111+
Func<DbContext, Task> clean)
112+
{
113+
// Skip the base implementation which calls EnsureCreatedResilientlyAsync()
114+
// For RuntimeMigration tests, we want an empty database without tables
115+
// so we can test creating and applying migrations from scratch.
116+
return Task.CompletedTask;
117+
}
118+
}
78119
}

test/EFCore.Sqlite.FunctionalTests/RuntimeMigrationSqliteTest.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Data.Common;
55
using Microsoft.Data.Sqlite;
66
using Microsoft.EntityFrameworkCore.Sqlite.Design.Internal;
7+
using Microsoft.EntityFrameworkCore.TestUtilities;
78

89
namespace Microsoft.EntityFrameworkCore;
910

@@ -18,7 +19,7 @@ protected override Assembly ProviderAssembly
1819
public class RuntimeMigrationSqliteFixture : RuntimeMigrationFixtureBase
1920
{
2021
protected override ITestStoreFactory TestStoreFactory
21-
=> SqliteTestStoreFactory.Instance;
22+
=> RuntimeMigrationSqliteTestStoreFactory.Instance;
2223

2324
protected override List<string> GetTableNames(DbConnection connection)
2425
{
@@ -33,4 +34,21 @@ protected override List<string> GetTableNames(DbConnection connection)
3334
return tables;
3435
}
3536
}
37+
38+
/// <summary>
39+
/// Custom test store factory for RuntimeMigration tests that doesn't seed the database.
40+
/// This is necessary because migration tests need to start with an empty database
41+
/// so they can test creating and applying migrations from scratch.
42+
/// </summary>
43+
private class RuntimeMigrationSqliteTestStoreFactory : SqliteTestStoreFactory
44+
{
45+
public static new RuntimeMigrationSqliteTestStoreFactory Instance { get; } = new();
46+
47+
private RuntimeMigrationSqliteTestStoreFactory()
48+
{
49+
}
50+
51+
public override TestStore GetOrCreate(string storeName)
52+
=> SqliteTestStore.GetExisting(storeName);
53+
}
3654
}

0 commit comments

Comments
 (0)