c# - 在 C# Net Core 3.1 单元测试中自动生成标识列
问题描述
我的基础课
public class Book {
public int Id { get; set;}
public string Title { get; set;}
}
public class Author {
public Author () {
BookList = new HashSet<Book> ();
for (int i = 0; i< 10; i++) {
var book = new Book() {
Title = "Funny book" + i;
}
BookList.Add(book);
}
}
public int Id { get; set;}
public string Name { get; set;}
public ICollection<Book> BookList { get; set; }
}
我的存储库类
public interface IBookRepository
{
Task<Book> CreateBook(Book book);
}
public class BookRepository : IBookRepository
{
public BookRepository(BookStoreContext context)
: base(context)
{
}
public async Task<Book> CreateBook(Book book)
{
if (book == null)
throw new ArgumentNullException("book cannot be null");
}
Context.Book.Add(book);
await Context.SaveChangesAsync().ConfigureAwait(false);
return book;
}
}
我正在使用以下实用程序类设置我的单元测试
public static class AuthorData
{
public static List<Author> GetData()
{
List<Author> authors = new List<Author>();
Author author1 = new Author()
{
Id = 100,
Name="author1"
};
authors.Add(author1);
Author author2 = new Author()
{
Id = 200,
Name="author2"
};
authors.Add(author2);
}
}
public static class BookData
{
public static List<Book> GetData()
{
List<Book> books = new List<Book>();
Book book1 = new Book()
{
Id = 1000,
Name="Wonderful book 1"
};
books.Add(book1);
Book book2 = new Book()
{
Id = 1001,
Name="Wonderful book 2"
};
books.Add(book2);
}
}
public class AuthorContextMock
{
public static BookStoreContext ConfigureSensorContext(IServiceCollection services)
{
services.AddDbContext<BookStoreContext>(c =>
c.UseInMemoryDatabase(Guid.NewGuid().ToString())
.UseQueryTrackingBehavior(QueryTrackingBehavior.TrackAll)
.EnableDetailedErrors()
.EnableSensitiveDataLogging());
var serviceProvider = services
.AddEntityFrameworkInMemoryDatabase()
.BuildServiceProvider();
var Context = serviceProvider.GetRequiredService<BookStoreContext>();
Context.Database.EnsureCreated();
Context.Authors.AddRange(AuthorData.GetData());
Context.Books.AddRange(BookData.GetData());
Context.SaveChanges();
return Context;
}
}
我的单元测试
[Fact]
public async Task CreateBookTest()
{
var context = BookContextMock.ConfigureBookContext(new ServiceCollection());
BookRepository repo = new BookRepository(context);
Book book = new BookSensor()
{
Title = "New Book 1",
};
var newBook = await repo.CreateBook(book);
}
在单元测试方法中,如果我没有为 book 对象指定 Id,它会抛出一个错误,指出 Id = 1000 的对象已被另一个实体跟踪。
这是我的推理:
(1) 当我创建作者测试数据时,它为每个作者创建了一些书籍。由于字段是 SQL 表的 Identity 列,因此在创建书籍时未指定 Id。
(2) 然后,我用指定的 ID 创建了我的图书测试数据。测试数据创建成功。
(3) 在单元测试期间,系统似乎对选择下一个可用 ID 感到困惑。
有没有办法在不指定 ID 的情况下解决问题?
单元测试适用于 netcore 2.1。单元测试转换为net core 3.1后,问题就出现了。
解决方案
如果您将 Book 类的定义更改为:
public class Book {
public string Id { get; set;}
public string Title { get; set;}
}
您可以使用以下方法即时生成新的 guid 来添加其他书籍:
Guid g = Guid.NewGuid();
然后,当您创建新书时,只需调用 g.ToString() 即可获取基础值并将其分配给 Id 属性。当然,您还必须更改后端数据库表的结构以支持这一点。
推荐阅读
- javascript - 如何使用按钮停止和继续功能?
- haskell - 是 ha 句柄还是 lambda 函数(或两者)?
- azure - 如何在 Azure Maps 中绘制圆形路径?
- java - 我的 Connect Four 游戏在运行时返回完整
- php - 使用密钥在 Swift 应用程序和 MySQL 数据库之间建立安全连接?
- python - Python 3:根据缓冲将二进制文件写入标准输出
- php - laravel-query-grouByMonth-groupByYear-sumdata
- java - Mockito:如何对 void 方法 java mockito 进行单元测试?
- anypoint-studio - 全局函数在预览中有效,但在运行代码时失败
- c# - 为什么 WslApi 在 WPF 应用程序中突然停止工作