2020-01-06 11:53:20 +03:00
# <img src="/src/icon.png" height="30px"> Verify.EntityFramework
2020-01-06 07:58:10 +03:00
2023-02-10 01:25:31 +03:00
[![Discussions ](https://img.shields.io/badge/Verify-Discussions-yellow?svg=true&label= )](https://github.com/orgs/VerifyTests/discussions)
2020-05-06 09:57:51 +03:00
[![Build status ](https://ci.appveyor.com/api/projects/status/g6njwv0aox62atu0?svg=true )](https://ci.appveyor.com/project/SimonCropp/verify-entityframework)
2021-11-05 13:54:47 +03:00
[![NuGet Status ](https://img.shields.io/nuget/v/Verify.EntityFramework.svg?label=Verify.EntityFramework )](https://www.nuget.org/packages/Verify.EntityFramework/)
[![NuGet Status ](https://img.shields.io/nuget/v/Verify.EntityFrameworkClassic.svg?label=Verify.EntityFrameworkClassic )](https://www.nuget.org/packages/Verify.EntityFrameworkClassic/)
2020-01-06 07:58:10 +03:00
2020-12-23 01:24:00 +03:00
Extends [Verify ](https://github.com/VerifyTests/Verify ) to allow snapshot testing with EntityFramework.
2020-01-06 07:58:10 +03:00
2023-09-21 15:04:45 +03:00
**See [Milestones ](../../milestones?state=closed ) for release notes.**
2020-07-26 04:53:24 +03:00
2022-04-03 04:00:42 +03:00
## NuGet packages
2020-01-06 07:58:10 +03:00
2020-02-19 02:19:19 +03:00
* https://nuget.org/packages/Verify.EntityFramework/
* https://nuget.org/packages/Verify.EntityFrameworkClassic/
2020-01-06 07:58:10 +03:00
2020-10-26 01:16:27 +03:00
## Enable
2020-01-06 07:58:10 +03:00
2021-06-13 12:36:29 +03:00
Enable VerifyEntityFramework once at assembly load time:
2020-01-06 07:58:10 +03:00
2020-04-16 01:34:23 +03:00
### EF Core
<!-- snippet: EnableCore -->
2020-10-11 00:25:07 +03:00
< a id = 'snippet-enablecore' > < / a >
2020-01-06 07:58:10 +03:00
```cs
2022-12-19 01:46:01 +03:00
static IModel GetDbModel()
{
var options = new DbContextOptionsBuilder< SampleDbContext > ();
options.UseSqlServer("fake");
using var data = new SampleDbContext(options.Options);
return data.Model;
}
2022-08-29 07:51:12 +03:00
[ModuleInitializer]
public static void Init()
{
2022-12-19 01:46:01 +03:00
var model = GetDbModel();
2023-02-07 02:49:18 +03:00
VerifyEntityFramework.Initialize(model);
2023-01-09 04:25:41 +03:00
}
2020-01-06 07:58:10 +03:00
```
2023-01-09 04:25:41 +03:00
< sup > < a href = '/src/Verify.EntityFramework.Tests/ModuleInitializer.cs#L5-L22' title = 'Snippet source file' > snippet source< / a > | < a href = '#snippet-enablecore' title = 'Start of snippet' > anchor< / a > < / sup >
2020-08-20 07:48:49 +03:00
<!-- endSnippet -->
2020-04-16 01:34:23 +03:00
2022-12-19 01:46:01 +03:00
The `GetDbModel` pattern allows an instance of the `IModel` to be stored for use when `IgnoreNavigationProperties` is called inside tests. This is optional, and instead can be passed explicitly to `IgnoreNavigationProperties` .
2020-04-16 01:34:23 +03:00
### EF Classic
<!-- snippet: EnableClassic -->
2020-10-11 00:25:07 +03:00
< a id = 'snippet-enableclassic' > < / a >
2020-02-18 09:12:51 +03:00
```cs
2022-08-29 07:51:12 +03:00
[ModuleInitializer]
2023-01-09 04:26:35 +03:00
public static void Init() =>
2023-02-07 02:49:18 +03:00
VerifyEntityFrameworkClassic.Initialize();
2022-08-29 07:51:12 +03:00
```
2023-02-07 09:14:09 +03:00
< sup > < a href = '/src/Verify.EntityFrameworkClassic.Tests/ModuleInitializer.cs#L3-L9' title = 'Snippet source file' > snippet source< / a > | < a href = '#snippet-enableclassic' title = 'Start of snippet' > anchor< / a > < / sup >
2020-08-20 07:48:49 +03:00
<!-- endSnippet -->
2020-08-19 10:02:41 +03:00
2020-10-26 01:16:27 +03:00
## Recording
2020-08-19 10:02:41 +03:00
2020-08-20 00:16:22 +03:00
Recording allows all commands executed by EF to be captured and then (optionally) verified.
2020-08-19 10:11:16 +03:00
2020-08-19 10:02:41 +03:00
2020-10-26 01:16:27 +03:00
### Enable
2020-08-19 10:02:41 +03:00
2021-06-21 07:47:11 +03:00
Call `EfRecording.EnableRecording()` on `DbContextOptionsBuilder` .
2020-08-19 10:02:41 +03:00
2020-08-20 00:31:56 +03:00
<!-- snippet: EnableRecording -->
2020-10-11 00:25:07 +03:00
< a id = 'snippet-enablerecording' > < / a >
2020-08-20 00:31:56 +03:00
```cs
2021-11-23 10:51:15 +03:00
var builder = new DbContextOptionsBuilder< SampleDbContext > ();
2020-08-20 00:31:56 +03:00
builder.UseSqlServer(connection);
builder.EnableRecording();
2021-11-23 10:51:15 +03:00
var data = new SampleDbContext(builder.Options);
2020-08-20 00:31:56 +03:00
```
2023-09-05 04:11:01 +03:00
< sup > < a href = '/src/Verify.EntityFramework.Tests/CoreTests.cs#L294-L301' title = 'Snippet source file' > snippet source< / a > | < a href = '#snippet-enablerecording' title = 'Start of snippet' > anchor< / a > < / sup >
2020-08-20 07:48:49 +03:00
<!-- endSnippet -->
2020-08-19 10:02:41 +03:00
2020-09-12 15:21:00 +03:00
`EnableRecording` should only be called in the test context.
2020-08-20 14:01:33 +03:00
2020-08-19 10:02:41 +03:00
2020-10-26 01:16:27 +03:00
### Usage
2020-08-19 10:11:16 +03:00
2021-06-21 07:47:11 +03:00
To start recording call `EfRecording.StartRecording()` . The results will be automatically included in verified file.
2020-08-19 10:11:16 +03:00
2020-08-19 10:02:41 +03:00
<!-- snippet: Recording -->
2020-10-11 00:25:07 +03:00
< a id = 'snippet-recording' > < / a >
2020-08-19 10:02:41 +03:00
```cs
2021-10-05 13:23:46 +03:00
var company = new Company
2020-08-19 10:02:41 +03:00
{
2020-10-26 00:55:58 +03:00
Content = "Title"
};
data.Add(company);
await data.SaveChangesAsync();
2020-08-19 10:02:41 +03:00
2021-06-21 07:47:11 +03:00
EfRecording.StartRecording();
2020-08-19 10:02:41 +03:00
2020-10-26 00:55:58 +03:00
await data.Companies
2022-12-19 01:46:01 +03:00
.Where(_ => _.Content == "Title")
2020-10-26 00:55:58 +03:00
.ToListAsync();
2020-08-19 10:02:41 +03:00
2021-12-22 14:01:00 +03:00
await Verify(data.Companies.Count());
2020-08-19 10:02:41 +03:00
```
2023-09-05 04:11:01 +03:00
< sup > < a href = '/src/Verify.EntityFramework.Tests/CoreTests.cs#L391-L408' title = 'Snippet source file' > snippet source< / a > | < a href = '#snippet-recording' title = 'Start of snippet' > anchor< / a > < / sup >
2020-08-20 07:48:49 +03:00
<!-- endSnippet -->
2020-08-19 10:02:41 +03:00
Will result in the following verified file:
<!-- snippet: CoreTests.Recording.verified.txt -->
2020-10-11 00:25:07 +03:00
< a id = 'snippet-CoreTests.Recording.verified.txt' > < / a >
2020-08-19 10:02:41 +03:00
```txt
2020-09-10 08:43:13 +03:00
{
2020-11-08 11:53:02 +03:00
target: 5,
2020-09-10 08:43:13 +03:00
sql: [
{
2020-11-08 11:53:02 +03:00
Type: ReaderExecutedAsync,
2022-08-09 08:05:41 +03:00
HasTransaction: false,
2021-05-22 04:16:37 +03:00
Text:
2020-11-08 11:53:02 +03:00
SELECT [c].[Id], [c].[Content]
2020-08-19 10:02:41 +03:00
FROM [Companies] AS [c]
2020-11-08 11:53:02 +03:00
WHERE [c].[Content] = N'Title'
2020-09-10 08:43:13 +03:00
},
{
2020-11-08 11:53:02 +03:00
Type: ReaderExecuted,
2022-08-09 08:05:41 +03:00
HasTransaction: false,
2021-05-22 04:16:37 +03:00
Text:
2020-11-08 11:53:02 +03:00
SELECT COUNT(*)
FROM [Companies] AS [c]
2020-09-10 08:43:13 +03:00
}
]
}
2020-08-19 10:02:41 +03:00
```
2022-08-09 08:05:41 +03:00
< sup > < a href = '/src/Verify.EntityFramework.Tests/CoreTests.Recording.verified.txt#L1-L20' title = 'Snippet source file' > snippet source< / a > | < a href = '#snippet-CoreTests.Recording.verified.txt' title = 'Start of snippet' > anchor< / a > < / sup >
2020-08-20 07:48:49 +03:00
<!-- endSnippet -->
2020-01-06 07:58:10 +03:00
2021-06-21 07:47:11 +03:00
Sql entries can be explicitly read using `EfRecording.FinishRecording` , optionally filtered, and passed to Verify:
2020-12-04 09:46:11 +03:00
<!-- snippet: RecordingSpecific -->
< a id = 'snippet-recordingspecific' > < / a >
```cs
2021-10-05 13:23:46 +03:00
var company = new Company
2020-12-04 09:46:11 +03:00
{
Content = "Title"
};
data.Add(company);
await data.SaveChangesAsync();
2021-06-21 07:47:11 +03:00
EfRecording.StartRecording();
2020-12-04 09:46:11 +03:00
await data.Companies
2022-12-19 01:46:01 +03:00
.Where(_ => _.Content == "Title")
2020-12-04 09:46:11 +03:00
.ToListAsync();
2021-06-21 07:47:11 +03:00
var entries = EfRecording.FinishRecording();
2020-12-04 09:46:11 +03:00
//TODO: optionally filter the results
2021-12-22 14:01:00 +03:00
await Verify(new
2020-12-04 09:46:11 +03:00
{
target = data.Companies.Count(),
sql = entries
});
```
2023-10-28 13:53:56 +03:00
< sup > < a href = '/src/Verify.EntityFramework.Tests/CoreTests.cs#L509-L532' title = 'Snippet source file' > snippet source< / a > | < a href = '#snippet-recordingspecific' title = 'Start of snippet' > anchor< / a > < / sup >
2020-12-04 09:46:11 +03:00
<!-- endSnippet -->
2020-10-26 01:16:27 +03:00
### DbContext spanning
2020-08-20 14:01:33 +03:00
2020-09-12 15:21:00 +03:00
`StartRecording` can be called on different DbContext instances (built from the same options) and the results will be aggregated.
2020-08-20 14:01:33 +03:00
<!-- snippet: MultiDbContexts -->
2020-10-11 00:25:07 +03:00
< a id = 'snippet-multidbcontexts' > < / a >
2020-08-20 14:01:33 +03:00
```cs
2021-10-05 13:23:46 +03:00
var builder = new DbContextOptionsBuilder< SampleDbContext > ();
2020-08-20 14:01:33 +03:00
builder.UseSqlServer(connectionString);
builder.EnableRecording();
2021-11-23 10:51:15 +03:00
await using var data1 = new SampleDbContext(builder.Options);
2021-06-21 07:47:11 +03:00
EfRecording.StartRecording();
2021-10-05 13:23:46 +03:00
var company = new Company
2020-08-20 14:01:33 +03:00
{
Content = "Title"
};
data1.Add(company);
await data1.SaveChangesAsync();
2021-11-23 10:51:15 +03:00
await using var data2 = new SampleDbContext(builder.Options);
2020-08-20 14:01:33 +03:00
await data2.Companies
2022-12-19 01:46:01 +03:00
.Where(_ => _.Content == "Title")
2020-08-20 14:01:33 +03:00
.ToListAsync();
2021-12-22 14:01:00 +03:00
await Verify(data2.Companies.Count());
2020-08-20 14:01:33 +03:00
```
2023-09-05 04:11:01 +03:00
< sup > < a href = '/src/Verify.EntityFramework.Tests/CoreTests.cs#L360-L382' title = 'Snippet source file' > snippet source< / a > | < a href = '#snippet-multidbcontexts' title = 'Start of snippet' > anchor< / a > < / sup >
2020-08-20 14:01:33 +03:00
<!-- endSnippet -->
<!-- snippet: CoreTests.MultiDbContexts.verified.txt -->
2020-10-11 00:25:07 +03:00
< a id = 'snippet-CoreTests.MultiDbContexts.verified.txt' > < / a >
2020-08-20 14:01:33 +03:00
```txt
2020-09-10 08:43:13 +03:00
{
2020-11-08 11:53:02 +03:00
target: 5,
2020-09-10 08:43:13 +03:00
sql: [
{
2020-11-08 11:53:02 +03:00
Type: ReaderExecutedAsync,
2022-11-09 06:38:22 +03:00
HasTransaction: false,
2020-09-10 08:43:13 +03:00
Parameters: {
2020-12-18 13:23:52 +03:00
@p0 (Int32): 0,
@p1 (String?): Title
2020-09-10 08:43:13 +03:00
},
2021-05-22 04:16:37 +03:00
Text:
2022-11-09 06:38:22 +03:00
SET IMPLICIT_TRANSACTIONS OFF;
2020-11-08 11:53:02 +03:00
SET NOCOUNT ON;
2020-08-20 14:01:33 +03:00
INSERT INTO [Companies] ([Id], [Content])
2020-11-08 11:53:02 +03:00
VALUES (@p0, @p1 );
2020-09-10 08:43:13 +03:00
},
{
2020-11-08 11:53:02 +03:00
Type: ReaderExecutedAsync,
2022-08-09 08:05:41 +03:00
HasTransaction: false,
2021-05-22 04:16:37 +03:00
Text:
2020-11-08 11:53:02 +03:00
SELECT [c].[Id], [c].[Content]
2020-08-20 14:01:33 +03:00
FROM [Companies] AS [c]
2020-11-08 11:53:02 +03:00
WHERE [c].[Content] = N'Title'
2020-09-10 08:43:13 +03:00
},
{
2020-11-08 11:53:02 +03:00
Type: ReaderExecuted,
2022-08-09 08:05:41 +03:00
HasTransaction: false,
2021-05-22 04:16:37 +03:00
Text:
2020-11-08 11:53:02 +03:00
SELECT COUNT(*)
FROM [Companies] AS [c]
2020-09-10 08:43:13 +03:00
}
]
}
2020-08-20 14:01:33 +03:00
```
2022-11-09 06:38:22 +03:00
< sup > < a href = '/src/Verify.EntityFramework.Tests/CoreTests.MultiDbContexts.verified.txt#L1-L33' title = 'Snippet source file' > snippet source< / a > | < a href = '#snippet-CoreTests.MultiDbContexts.verified.txt' title = 'Start of snippet' > anchor< / a > < / sup >
2020-08-20 14:01:33 +03:00
<!-- endSnippet -->
2020-10-26 01:16:27 +03:00
## ChangeTracking
2020-01-07 05:08:39 +03:00
2020-08-19 06:33:30 +03:00
Added, deleted, and Modified entities can be verified by performing changes on a DbContext and then verifying the instance of ChangeTracking. This approach leverages the [EntityFramework ChangeTracker ](https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.changetracking.changetracker ).
2020-01-07 05:08:39 +03:00
2020-10-26 01:16:27 +03:00
### Added entity
2020-01-06 07:58:10 +03:00
2020-01-06 13:38:28 +03:00
This test:
<!-- snippet: Added -->
2020-10-11 00:25:07 +03:00
< a id = 'snippet-added' > < / a >
2020-01-06 13:38:28 +03:00
```cs
2020-06-07 10:06:09 +03:00
[Test]
2020-01-06 13:38:28 +03:00
public async Task Added()
{
var options = DbContextOptions();
2021-11-23 10:51:15 +03:00
await using var data = new SampleDbContext(options);
2021-10-05 13:23:46 +03:00
var company = new Company
2020-07-07 06:40:02 +03:00
{
Content = "before"
};
data.Add(company);
2021-12-22 14:01:00 +03:00
await Verify(data.ChangeTracker);
2020-01-06 13:38:28 +03:00
}
```
2022-10-15 14:08:33 +03:00
< sup > < a href = '/src/Verify.EntityFramework.Tests/CoreTests.cs#L5-L21' title = 'Snippet source file' > snippet source< / a > | < a href = '#snippet-added' title = 'Start of snippet' > anchor< / a > < / sup >
2020-08-20 07:48:49 +03:00
<!-- endSnippet -->
2020-01-06 13:38:28 +03:00
Will result in the following verified file:
2020-01-06 07:58:10 +03:00
2020-04-16 01:34:23 +03:00
<!-- snippet: CoreTests.Added.verified.txt -->
2020-10-11 00:25:07 +03:00
< a id = 'snippet-CoreTests.Added.verified.txt' > < / a >
2020-01-06 13:38:28 +03:00
```txt
{
Added: {
Company: {
2020-01-06 13:39:54 +03:00
Id: 0,
2020-11-08 11:53:02 +03:00
Content: before
2020-01-06 13:38:28 +03:00
}
}
}
```
2020-10-11 00:25:07 +03:00
< sup > < a href = '/src/Verify.EntityFramework.Tests/CoreTests.Added.verified.txt#L1-L8' title = 'Snippet source file' > snippet source< / a > | < a href = '#snippet-CoreTests.Added.verified.txt' title = 'Start of snippet' > anchor< / a > < / sup >
2020-08-20 07:48:49 +03:00
<!-- endSnippet -->
2020-01-06 13:38:28 +03:00
2020-10-26 01:16:27 +03:00
### Deleted entity
2020-01-06 07:58:10 +03:00
This test:
2020-01-06 13:38:28 +03:00
<!-- snippet: Deleted -->
2020-10-11 00:25:07 +03:00
< a id = 'snippet-deleted' > < / a >
2020-01-06 13:38:28 +03:00
```cs
2020-06-07 10:06:09 +03:00
[Test]
2020-01-06 13:38:28 +03:00
public async Task Deleted()
{
var options = DbContextOptions();
2021-11-23 10:51:15 +03:00
await using var data = new SampleDbContext(options);
2022-04-03 04:00:42 +03:00
data.Add(new Company
{
Content = "before"
});
2020-04-03 03:32:46 +03:00
await data.SaveChangesAsync();
2020-01-06 13:38:28 +03:00
2020-04-03 03:32:46 +03:00
var company = data.Companies.Single();
data.Companies.Remove(company);
2021-12-22 14:01:00 +03:00
await Verify(data.ChangeTracker);
2020-01-06 13:38:28 +03:00
}
```
2022-10-15 14:08:33 +03:00
< sup > < a href = '/src/Verify.EntityFramework.Tests/CoreTests.cs#L23-L42' title = 'Snippet source file' > snippet source< / a > | < a href = '#snippet-deleted' title = 'Start of snippet' > anchor< / a > < / sup >
2020-08-20 07:48:49 +03:00
<!-- endSnippet -->
2020-01-06 07:58:10 +03:00
Will result in the following verified file:
2020-04-16 01:34:23 +03:00
<!-- snippet: CoreTests.Deleted.verified.txt -->
2020-10-11 00:25:07 +03:00
< a id = 'snippet-CoreTests.Deleted.verified.txt' > < / a >
2020-01-06 13:38:28 +03:00
```txt
{
Deleted: {
Company: {
Id: 0
}
}
}
```
2020-10-11 00:25:07 +03:00
< sup > < a href = '/src/Verify.EntityFramework.Tests/CoreTests.Deleted.verified.txt#L1-L7' title = 'Snippet source file' > snippet source< / a > | < a href = '#snippet-CoreTests.Deleted.verified.txt' title = 'Start of snippet' > anchor< / a > < / sup >
2020-08-20 07:48:49 +03:00
<!-- endSnippet -->
2020-01-06 13:38:28 +03:00
2020-10-26 01:16:27 +03:00
### Modified entity
2020-01-06 13:38:28 +03:00
This test:
<!-- snippet: Modified -->
2020-10-11 00:25:07 +03:00
< a id = 'snippet-modified' > < / a >
2020-01-06 13:38:28 +03:00
```cs
2020-06-07 10:06:09 +03:00
[Test]
2020-01-06 13:38:28 +03:00
public async Task Modified()
{
var options = DbContextOptions();
2021-11-23 10:51:15 +03:00
await using var data = new SampleDbContext(options);
var company = new Company
2020-07-07 06:40:02 +03:00
{
Content = "before"
};
2020-04-03 03:32:46 +03:00
data.Add(company);
await data.SaveChangesAsync();
2020-01-06 13:38:28 +03:00
2020-04-03 03:32:46 +03:00
data.Companies.Single().Content = "after";
2021-12-22 14:01:00 +03:00
await Verify(data.ChangeTracker);
2020-01-06 13:38:28 +03:00
}
```
2022-10-15 14:08:33 +03:00
< sup > < a href = '/src/Verify.EntityFramework.Tests/CoreTests.cs#L44-L63' title = 'Snippet source file' > snippet source< / a > | < a href = '#snippet-modified' title = 'Start of snippet' > anchor< / a > < / sup >
2020-08-20 07:48:49 +03:00
<!-- endSnippet -->
2020-01-06 07:58:10 +03:00
2020-01-06 13:38:28 +03:00
Will result in the following verified file:
2020-04-16 01:34:23 +03:00
<!-- snippet: CoreTests.Modified.verified.txt -->
2020-10-11 00:25:07 +03:00
< a id = 'snippet-CoreTests.Modified.verified.txt' > < / a >
2020-02-18 09:12:51 +03:00
```txt
{
Modified: {
Company: {
Id: 0,
Content: {
2020-11-08 11:53:02 +03:00
Original: before,
Current: after
2020-02-18 09:12:51 +03:00
}
}
}
}
```
2020-10-11 00:25:07 +03:00
< sup > < a href = '/src/Verify.EntityFramework.Tests/CoreTests.Modified.verified.txt#L1-L11' title = 'Snippet source file' > snippet source< / a > | < a href = '#snippet-CoreTests.Modified.verified.txt' title = 'Start of snippet' > anchor< / a > < / sup >
2020-08-20 07:48:49 +03:00
<!-- endSnippet -->
2020-01-06 07:58:10 +03:00
2020-10-26 01:16:27 +03:00
## Queryable
2020-01-06 15:56:57 +03:00
This test:
<!-- snippet: Queryable -->
2020-10-11 00:25:07 +03:00
< a id = 'snippet-queryable' > < / a >
2020-01-06 15:56:57 +03:00
```cs
2020-10-26 00:55:58 +03:00
var queryable = data.Companies
2022-12-19 01:46:01 +03:00
.Where(_ => _.Content == "value");
2021-12-22 14:01:00 +03:00
await Verify(queryable);
2020-01-06 15:56:57 +03:00
```
2023-09-05 04:11:01 +03:00
< sup > < a href = '/src/Verify.EntityFramework.Tests/CoreTests.cs#L253-L259' title = 'Snippet source file' > snippet source< / a > | < a href = '#snippet-queryable' title = 'Start of snippet' > anchor< / a > < / sup >
2020-08-20 07:48:49 +03:00
<!-- endSnippet -->
2020-01-06 15:56:57 +03:00
Will result in the following verified file:
2020-04-16 01:34:23 +03:00
### EF Core
2023-09-05 04:29:46 +03:00
<!-- snippet: CoreTests.Queryable.verified.txt -->
< a id = 'snippet-CoreTests.Queryable.verified.txt' > < / a >
2023-09-05 04:11:01 +03:00
```txt
[
{
Content: value
}
]
```
2023-09-05 04:29:46 +03:00
< sup > < a href = '/src/Verify.EntityFramework.Tests/CoreTests.Queryable.verified.txt#L1-L5' title = 'Snippet source file' > snippet source< / a > | < a href = '#snippet-CoreTests.Queryable.verified.txt' title = 'Start of snippet' > anchor< / a > < / sup >
2023-09-05 04:11:01 +03:00
<!-- endSnippet -->
2023-09-05 04:29:46 +03:00
<!-- snippet: CoreTests.Queryable.verified.sql -->
< a id = 'snippet-CoreTests.Queryable.verified.sql' > < / a >
```sql
2020-07-07 06:40:02 +03:00
SELECT [c].[Id], [c].[Content]
FROM [Companies] AS [c]
WHERE [c].[Content] = N'value'
2020-02-18 09:12:51 +03:00
```
2023-09-05 04:29:46 +03:00
< sup > < a href = '/src/Verify.EntityFramework.Tests/CoreTests.Queryable.verified.sql#L1-L3' title = 'Snippet source file' > snippet source< / a > | < a href = '#snippet-CoreTests.Queryable.verified.sql' title = 'Start of snippet' > anchor< / a > < / sup >
2020-08-20 07:48:49 +03:00
<!-- endSnippet -->
2020-04-16 01:34:23 +03:00
### EF Classic
<!-- snippet: ClassicTests.Queryable.verified.txt -->
2020-10-11 00:25:07 +03:00
< a id = 'snippet-ClassicTests.Queryable.verified.txt' > < / a >
2020-04-16 01:34:23 +03:00
```txt
2020-07-07 06:40:02 +03:00
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Content] AS [Content]
FROM [dbo].[Companies] AS [Extent1]
WHERE N'value' = [Extent1].[Content]
2020-04-16 01:34:23 +03:00
```
2020-10-11 00:25:07 +03:00
< sup > < a href = '/src/Verify.EntityFrameworkClassic.Tests/ClassicTests.Queryable.verified.txt#L1-L5' title = 'Snippet source file' > snippet source< / a > | < a href = '#snippet-ClassicTests.Queryable.verified.txt' title = 'Start of snippet' > anchor< / a > < / sup >
2020-08-20 07:48:49 +03:00
<!-- endSnippet -->
2020-01-06 15:56:57 +03:00
2020-10-26 01:16:27 +03:00
## AllData
This test:
<!-- snippet: AllData -->
< a id = 'snippet-alldata' > < / a >
```cs
2021-12-22 14:01:00 +03:00
await Verify(data.AllData())
2022-05-17 02:11:48 +03:00
.AddExtraSettings(
serializer =>
serializer.TypeNameHandling = TypeNameHandling.Objects);
2020-10-26 01:16:27 +03:00
```
2022-12-19 01:46:01 +03:00
< sup > < a href = '/src/Verify.EntityFramework.Tests/CoreTests.cs#L232-L239' title = 'Snippet source file' > snippet source< / a > | < a href = '#snippet-alldata' title = 'Start of snippet' > anchor< / a > < / sup >
2020-10-26 01:16:27 +03:00
<!-- endSnippet -->
Will result in the following verified file with all data in the database:
<!-- snippet: CoreTests.AllData.verified.txt -->
< a id = 'snippet-CoreTests.AllData.verified.txt' > < / a >
```txt
2020-10-26 01:45:27 +03:00
[
{
2020-11-08 11:53:02 +03:00
$type: Company,
2022-05-31 03:27:14 +03:00
Id: 1,
2020-11-08 11:53:02 +03:00
Content: Company1
2020-10-26 01:45:27 +03:00
},
{
2020-11-08 11:53:02 +03:00
$type: Company,
2022-05-31 03:27:14 +03:00
Id: 4,
2020-11-08 11:53:02 +03:00
Content: Company2
2020-10-26 01:45:27 +03:00
},
{
2020-11-08 11:53:02 +03:00
$type: Company,
2022-05-31 03:27:14 +03:00
Id: 6,
2020-11-08 11:53:02 +03:00
Content: Company3
2020-10-26 01:45:27 +03:00
},
{
2020-11-08 11:53:02 +03:00
$type: Company,
2022-05-31 03:27:14 +03:00
Id: 7,
2020-11-08 11:53:02 +03:00
Content: Company4
2020-10-26 01:45:27 +03:00
},
{
2020-11-08 11:53:02 +03:00
$type: Employee,
2022-05-31 03:27:14 +03:00
Id: 2,
CompanyId: 1,
2020-11-08 11:53:02 +03:00
Content: Employee1,
2020-10-26 01:45:27 +03:00
Age: 25
},
{
2020-11-08 11:53:02 +03:00
$type: Employee,
2022-05-31 03:27:14 +03:00
Id: 3,
CompanyId: 1,
2020-11-08 11:53:02 +03:00
Content: Employee2,
2020-10-26 01:45:27 +03:00
Age: 31
},
{
2020-11-08 11:53:02 +03:00
$type: Employee,
2022-05-31 03:27:14 +03:00
Id: 5,
CompanyId: 4,
2020-11-08 11:53:02 +03:00
Content: Employee4,
2020-10-26 01:45:27 +03:00
Age: 34
}
]
2020-10-26 01:16:27 +03:00
```
2020-10-26 01:45:27 +03:00
< sup > < a href = '/src/Verify.EntityFramework.Tests/CoreTests.AllData.verified.txt#L1-L43' title = 'Snippet source file' > snippet source< / a > | < a href = '#snippet-CoreTests.AllData.verified.txt' title = 'Start of snippet' > anchor< / a > < / sup >
2020-10-26 01:16:27 +03:00
<!-- endSnippet -->
2021-03-30 06:08:18 +03:00
## IgnoreNavigationProperties
`IgnoreNavigationProperties` extends `SerializationSettings` to exclude all navigation properties from serialization:
<!-- snippet: IgnoreNavigationProperties -->
< a id = 'snippet-ignorenavigationproperties' > < / a >
```cs
[Test]
public async Task IgnoreNavigationProperties()
{
var options = DbContextOptions();
2021-11-23 10:51:15 +03:00
await using var data = new SampleDbContext(options);
2021-03-30 06:08:18 +03:00
2021-10-05 13:23:46 +03:00
var company = new Company
2021-03-30 06:08:18 +03:00
{
Content = "company"
};
2021-10-05 13:23:46 +03:00
var employee = new Employee
2021-03-30 06:08:18 +03:00
{
Content = "employee",
Company = company
};
2021-12-22 14:01:00 +03:00
await Verify(employee)
2022-12-19 01:46:01 +03:00
.IgnoreNavigationProperties();
2021-03-30 06:08:18 +03:00
}
```
2022-10-15 14:08:33 +03:00
< sup > < a href = '/src/Verify.EntityFramework.Tests/CoreTests.cs#L65-L87' title = 'Snippet source file' > snippet source< / a > | < a href = '#snippet-ignorenavigationproperties' title = 'Start of snippet' > anchor< / a > < / sup >
2021-03-30 06:08:18 +03:00
<!-- endSnippet -->
2022-04-03 04:00:42 +03:00
2022-06-29 12:30:28 +03:00
### Ignore globally
2022-05-31 03:42:11 +03:00
<!-- snippet: IgnoreNavigationPropertiesGlobal -->
< a id = 'snippet-ignorenavigationpropertiesglobal' > < / a >
```cs
var options = DbContextOptions();
using var data = new SampleDbContext(options);
2022-12-19 01:46:01 +03:00
VerifyEntityFramework.IgnoreNavigationProperties();
2022-05-31 03:42:11 +03:00
```
2022-12-19 01:46:01 +03:00
< sup > < a href = '/src/Verify.EntityFramework.Tests/CoreTests.cs#L115-L121' title = 'Snippet source file' > snippet source< / a > | < a href = '#snippet-ignorenavigationpropertiesglobal' title = 'Start of snippet' > anchor< / a > < / sup >
2022-05-31 03:42:11 +03:00
<!-- endSnippet -->
2022-04-03 03:52:53 +03:00
## WebApplicationFactory
2022-06-29 12:30:28 +03:00
To be able to use [WebApplicationFactory ](https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.testing.webapplicationfactory-1 ) for [integration testing ](https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests ) an identifier must be used to be able to retrieve the recorded commands. Start by enable recording with a unique identifier, for example the test name or a GUID:
2022-04-03 03:52:53 +03:00
<!-- snippet: EnableRecordingWithIdentifier -->
< a id = 'snippet-enablerecordingwithidentifier' > < / a >
```cs
2023-10-28 13:53:56 +03:00
protected override void ConfigureWebHost(IWebHostBuilder webBuilder)
2022-04-03 03:52:53 +03:00
{
2023-10-28 13:50:47 +03:00
var dataBuilder = new DbContextOptionsBuilder< SampleDbContext > ()
2023-10-28 13:45:54 +03:00
.EnableRecording(name)
.UseSqlite($"Data Source={name};Mode=Memory;Cache=Shared");
2023-10-28 13:53:56 +03:00
webBuilder.ConfigureTestServices(
_ => _ .AddScoped(_ => dataBuilder.Options));
2023-10-28 13:50:47 +03:00
}
2022-04-03 03:52:53 +03:00
```
2023-10-28 13:53:56 +03:00
< sup > < a href = '/src/Verify.EntityFramework.Tests/CoreTests.cs#L467-L478' title = 'Snippet source file' > snippet source< / a > | < a href = '#snippet-enablerecordingwithidentifier' title = 'Start of snippet' > anchor< / a > < / sup >
2022-04-03 03:52:53 +03:00
<!-- endSnippet -->
2022-04-03 04:00:42 +03:00
Then use the same identifier for recording:
2022-04-03 03:52:53 +03:00
<!-- snippet: RecordWithIdentifier -->
< a id = 'snippet-recordwithidentifier' > < / a >
```cs
var httpClient = factory.CreateClient();
EfRecording.StartRecording(testName);
var companies = await httpClient.GetFromJsonAsync< Company [ ] > ("/companies");
var entries = EfRecording.FinishRecording(testName);
```
2023-09-05 04:11:01 +03:00
< sup > < a href = '/src/Verify.EntityFramework.Tests/CoreTests.cs#L441-L451' title = 'Snippet source file' > snippet source< / a > | < a href = '#snippet-recordwithidentifier' title = 'Start of snippet' > anchor< / a > < / sup >
2022-04-03 03:52:53 +03:00
<!-- endSnippet -->
The results will not be automatically included in verified file so it will have to be verified manually:
<!-- snippet: VerifyRecordedCommandsWithIdentifier -->
< a id = 'snippet-verifyrecordedcommandswithidentifier' > < / a >
```cs
await Verify(new
{
target = companies!.Length,
sql = entries
});
```
2023-09-05 04:11:01 +03:00
< sup > < a href = '/src/Verify.EntityFramework.Tests/CoreTests.cs#L453-L461' title = 'Snippet source file' > snippet source< / a > | < a href = '#snippet-verifyrecordedcommandswithidentifier' title = 'Start of snippet' > anchor< / a > < / sup >
2022-04-03 03:52:53 +03:00
<!-- endSnippet -->
2020-10-26 01:16:27 +03:00
2022-04-03 04:00:42 +03:00
2020-01-06 07:58:10 +03:00
## Icon
2021-10-14 10:51:25 +03:00
[Database ](https://thenounproject.com/term/database/310841/ ) designed by [Creative Stall ](https://thenounproject.com/creativestall/ ) from [The Noun Project ](https://thenounproject.com ).