Skip to content

Commit 0f08612

Browse files
authored
Updated readme examples (#114)
1 parent e860480 commit 0f08612

File tree

1 file changed

+93
-71
lines changed

1 file changed

+93
-71
lines changed

README.md

Lines changed: 93 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,10 @@
66
[![Nuget](https://img.shields.io/nuget/v/EntityFrameworkCore.AutoFixture?logo=nuget&style=flat-square)](https://www.nuget.org/packages/EntityFrameworkCore.AutoFixture/)
77
[![GitHub](https://img.shields.io/github/license/aivascu/EntityFrameworkCore.AutoFixture?logo=MIT&style=flat-square)](https://licenses.nuget.org/MIT)
88

9-
**EntityFrameworkCore.AutoFixture** is the logical product
10-
of [Entity Framework Core](https://docs.microsoft.com/en-us/ef/core/) in-memory providers
11-
and [AutoFixture](https://github.com/AutoFixture/AutoFixture).
12-
13-
Using **EntityFrameworkCore.AutoFixture** you can greatly reduce the boilerplate work necessary to unit test code that
14-
uses **Entity Framework Core** database contexts (see [examples](#examples)). You'll appreciate this library if you are
15-
already using **AutoFixture** as your auto-mocking container.
16-
17-
**EntityFrameworkCore.AutoFixture** extens **AutoFixture** with the ability to create fully functional `DbContext`
18-
instances, with very little setup code.
9+
**EntityFrameworkCore.AutoFixture** is a library that helps with testing code that uses [Entity Framework](https://docs.microsoft.com/en-us/ef/core/), by reducing the boilerplate code necessary to set up database contexts (see [examples](#examples)), with the help of [AutoFixture](https://github.com/AutoFixture/AutoFixture).
1910

2011
Unlike other libraries for faking EF contexts, **EntityFrameworkCore.AutoFixture** does not use mocking frameworks or
21-
dynamic proxies in order to create `DbContext` instances, instead it uses the Microsoft's own
22-
in-memory [providers](https://docs.microsoft.com/en-us/ef/core/miscellaneous/testing/) for EF Core. This allows to make
23-
less assumptions (read as: mock setups) in your tests about how the `DbContext` will behave in the real environment.
12+
dynamic proxies in to create database contexts, instead it uses the actual database [providers](https://docs.microsoft.com/en-us/ef/core/miscellaneous/testing/). This ensures the tests will behave a lot more similar to the code in the production environment, with little to no effort.
2413

2514
#### :warning: .NET Standard 2.0 in EF Core v3.0.x :warning:
2615

@@ -31,37 +20,28 @@ version of Entity Framework Core.
3120

3221
## Features
3322

34-
**EntityFrameworkCore.AutoFixture** offers three customizations to aid your unit testing workflow:
23+
**EntityFrameworkCore.AutoFixture** offers three customizations to help your unit testing workflow:
3524

36-
- `InMemoryContextCustomization` - customizes fixtures to use the In-Memory database provider when creating *DbContext*
37-
instances
38-
- `SqliteContextCustomization` - customizes fixtures to use the SQLite database provider when creating *DbContext*
39-
instances.
40-
By default the customization will create contexts for an in-memory *connection string* (i.e. `DataSource=:memory:`).
41-
This can be changed by providing the fixture a predefined `SqliteConnection` instance.
42-
- `DbContextCustomization` - serves as the base customization for the other two implementations. The customization can
43-
be used, in more advanced scenarios, when you want to extend the fixtures with your own specimen builders.
25+
- `InMemoryCustomization` - Customizes fixtures to create contexts using the In-Memory database provider
26+
- `SqliteCustomization` - Customizes fixtures to create contexts using the SQLite database provider
27+
- `DbContextCustomization` - A base class for database provider customizations. Can be used, in more advanced scenarios, for example, to extend the existing functionality or create customizations for other providers.
4428

4529
## Examples
4630

47-
The examples below demonstrate, the possible ways of using the library in [xUnit](https://github.com/xunit/xunit) test
48-
projects, both with `[Fact]` and `[Theory]` tests.
31+
The examples below demonstrate, the possible ways of using the library in [xUnit](https://xunit.net) test projects, both with `[Fact]` and `[Theory]` tests.
4932

50-
The library is not limited to `xUnit` and can be used with other testing frameworks like `NUnit` and `MSTest`, since it
51-
only provides a few `Customization` implementations.
33+
The library is not limited to `xUnit` and can be used with other testing frameworks like [NUnit](https://nunit.org) and [MSTest](https://docs.microsoft.com/en-us/dotnet/core/testing/unit-testing-with-mstest), since it only provides the customizations.
5234

5335
### Using In-Memory database provider
5436

37+
By default this customization will configure all contexts to use the [in-memory](https://docs.microsoft.com/en-us/ef/core/testing/testing-without-the-database#in-memory-provider) database provider for Enity Framework, and will create the database, giving you a ready to use context.
38+
5539
```csharp
5640
[Fact]
57-
public async Task CanUseGeneratedContext()
41+
public async Task CanSavesCustomers()
5842
{
5943
// Arrange
60-
var fixture = new Fixture().Customize(new InMemoryContextCustomization
61-
{
62-
AutoCreateDatabase = true,
63-
OmitDbSets = true
64-
});
44+
var fixture = new Fixture().Customize(new InMemoryCustomization());
6545
var context = fixture.Create<TestDbContext>();
6646

6747
// Act
@@ -73,14 +53,25 @@ public async Task CanUseGeneratedContext()
7353
}
7454
```
7555

76-
The next example uses a custom `AutoData` attribute `AutoDomainDataWithInMemoryContext` that customizes the fixture with
77-
the same customization as in the example above. This helps abstract away even more setup code.
56+
With the default configuration, the custmization will set the store name to `TestDatabase` and will suffix it with a random string to ensure the name is unique. After the context is created it will run `Database.EnsureCreated()` to create the database.
57+
58+
This behavior can be changed by setting the corresponding values in the customizaiton initializer.
7859

7960
```csharp
80-
[Theory, InMemoryData]
81-
public async Task CanUseGeneratedContext(TestDbContext context)
61+
[Fact]
62+
public async Task CanSavesCustomers()
8263
{
83-
// Arrange & Act
64+
// Arrange
65+
var fixture = new Fixture().Customize(new InMemoryCustomization
66+
{
67+
DatabaseName = "MyCoolDatabase", // Sets the store name to "MyCoolDatabase"
68+
UseUniqueNames = false, // No suffix for store names. All contexts will connect to same store
69+
OnCreate = OnCreateAction.Migrate // Will run Database.Migrate()
70+
// Use OnCreateAction.None to skip creating the database
71+
});
72+
var context = fixture.Create<TestDbContext>();
73+
74+
// Act
8475
context.Customers.Add(new Customer("Jane Smith"));
8576
await context.SaveChangesAsync();
8677

@@ -89,41 +80,44 @@ public async Task CanUseGeneratedContext(TestDbContext context)
8980
}
9081
```
9182

92-
The attribute used in the test above might look something like the following.
83+
To encapsulate the configuration and remove even more of the boilerplate, use the `AutoData` attributes offered by AutoFixture.
9384

9485
```csharp
95-
public class InMemoryDataAttribute : AutoDataAttribute
86+
public class PersistenceDataAttribute : AutoDataAttribute
9687
{
97-
public InMemoryDataAttribute()
98-
: base(() => new Fixture()
99-
.Customize(new InMemoryContextCustomization
100-
{
101-
OmitDbSets = true,
102-
AutoCreateDatabase = true
103-
}))
88+
public PersistenceDataAttribute()
89+
: base(() => new Fixture().Customize(new InMemoryCustomization {
90+
UseUniqueNames = false,
91+
OnCreate = OnCreateAction.Migrate
92+
}))
10493
{
10594
}
10695
}
10796
```
10897

98+
```csharp
99+
[Theory, PersistenceData] // Notice the data attribute
100+
public async Task CanUseGeneratedContext(TestDbContext context)
101+
{
102+
// Arrange & Act
103+
context.Customers.Add(new Customer("Jane Smith"));
104+
await context.SaveChangesAsync();
105+
106+
// Assert
107+
context.Customers.Should().Contain(x => x.Name == "Jane Smith");
108+
}
109+
```
110+
109111
### Using SQLite database provider
110112

111-
When using the SQLite database provider there is another configuration available in the customization,
112-
called `AutoOpenConnection` which allows to automatically open database connections, after they are resolved from the
113-
fixture. The option is turned off by default in v1, but might become the default in next major releases.
113+
By default this customization will configure all contexts to use the [SQLite](https://docs.microsoft.com/en-us/ef/core/testing/testing-without-the-database#sqlite-in-memory) database provider for Enity Framework, and will automatically create the database, giving you a ready to use context.
114114

115115
```csharp
116116
[Fact]
117117
public async Task CanUseGeneratedContext()
118118
{
119119
// Arrange
120-
var fixture = new Fixture()
121-
.Customize(new SqliteContextCustomization
122-
{
123-
AutoCreateDatabase = true,
124-
AutoOpenConnection = true,
125-
OmitDbSets = true
126-
});
120+
var fixture = new Fixture().Customize(new SqliteCustomization());
127121
var context = fixture.Create<TestDbContext>();
128122

129123
// Act
@@ -135,38 +129,66 @@ public async Task CanUseGeneratedContext()
135129
}
136130
```
137131

138-
The same test can be written like this, by using a custom data attribute.
132+
With the default configuration, the custmization will set the connection string to `Data Source=:memory:`, will open the connection and after the context is created it will run `Database.EnsureCreated()` to create the database.
133+
134+
This behavior can be changed by setting the corresponding values in the customizaiton initializer.
139135

140136
```csharp
141-
[Theory, SqliteData]
142-
public void CanUseResolvedContextInstance(TestDbContext context)
137+
[Fact]
138+
public async Task CanSavesCustomers()
143139
{
144-
// Arrange & Act
140+
// Arrange
141+
var fixture = new Fixture().Customize(new SqliteCustomization
142+
{
143+
ConnectionString = "Data Source=MyDatabase.sqlite;Cache=Shared;", // Sets the connection string to connect to a file
144+
AutoOpenConnection = false, // Disables opening the connection by default. Affects all SqliteConnection instances.
145+
OnCreate = OnCreateAction.None // Will to skip creating the database
146+
// Use OnCreateAction.EnsureCreated to run Database.EnsureCreated() automatically
147+
// Use OnCreateAction.Migrate to run Database.Migrate() automatically
148+
});
149+
var connection = fixture.Freeze<SqliteConnection>();
150+
var context = fixture.Create<TestDbContext>();
151+
connection.Open();
152+
context.Database.Migrate();
153+
154+
// Act
145155
context.Customers.Add(new Customer("Jane Smith"));
146-
context.SaveChanges();
156+
await context.SaveChangesAsync();
147157

148158
// Assert
149159
context.Customers.Should().Contain(x => x.Name == "Jane Smith");
150160
}
151161
```
152162

163+
To encapsulate the configuration and remove even more of the boilerplate, use the `AutoData` attributes offered by AutoFixture.
164+
153165
```csharp
154-
public class SqliteDataAttribute : AutoDataAttribute
166+
public class PersistenceDataAttribute : AutoDataAttribute
155167
{
156-
public SqliteDataAttribute()
157-
: base(() => new Fixture()
158-
.Customize(new SqliteContextCustomization
159-
{
160-
OmitDbSets = true,
161-
AutoOpenConnection = true,
162-
AutoCreateDatabase = true
163-
}))
168+
public PersistenceDataAttribute()
169+
: base(() => new Fixture().Customize(new SqliteCustomization {
170+
ConnectionString = "Data Source=MyDatabase;Mode=Memory;Cache=Shared;"
171+
OnCreate = OnCreateAction.Migrate
172+
}))
164173
{
165174
}
166175
}
167176
```
168177

178+
```csharp
179+
[Theory, PersistenceData] // Notice the data attribute
180+
public async Task CanUseGeneratedContext(TestDbContext context)
181+
{
182+
// Arrange & Act
183+
context.Customers.Add(new Customer("Jane Smith"));
184+
await context.SaveChangesAsync();
185+
186+
// Assert
187+
context.Customers.Should().Contain(x => x.Name == "Jane Smith");
188+
}
189+
```
190+
169191
## License
170192

171193
Copyright &copy; 2019 [Andrei Ivascu](https://github.com/aivascu).<br/>
172-
This project is [MIT](https://github.com/aivascu/EntityFrameworkCore.AutoFixture/blob/master/LICENSE) licensed.
194+
This project is [MIT](https://github.com/aivascu/EntityFrameworkCore.AutoFixture/blob/master/LICENSE) licensed.

0 commit comments

Comments
 (0)