我的基础课
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);
}
在单元测试方法中,如果我没有为书本对象指定ID,则它将引发错误,表示另一个实体已经跟踪了ID = 1000的对象。
这是我的理由:
((1)当我创建作者测试数据时,它为每个作者创建了许多书籍。由于该字段是SQL表的“标识”列,因此创建这些书时没有指定ID。
((2)然后,我创建了具有指定ID的图书测试数据。测试数据已成功创建。
(3)在单元测试期间,系统似乎很困惑以获取下一个可用的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();
然后,当您创建新Book时,只需调用g.ToString()即可获取基础值并将其分配给Id属性。当然,您还必须更改后端数据库表的结构以支持此操作。