我正在尝试运行一些单元测试,我需要做[TestInitialize]
的事情。
我在this post找到了一些信息。我不知道如何解决它,因为它对我没有意义。
[TestInitialize]
public void TestInitialize()
{
mock = new Mock<ILibraryRepository>();
books = new List<Book>()
{
new Book { Id = 0, Title = "Title 0", Edition = 0, PublicationDate = DateTime.Now, Author = { Id = 0, Name = "Author 0", DateOfBirth = DateTime.Now, DateOfDeath = DateTime.Now }, AuthorId = 0 },
new Book { Id = 1, Title = "Title 1", Edition = 1, PublicationDate = DateTime.Now, Author = { Id = 1, Name = "Author 1", DateOfBirth = DateTime.Now, DateOfDeath = DateTime.Now }, AuthorId = 1 },
new Book { Id = 2, Title = "Title 2", Edition = 2, PublicationDate = DateTime.Now, Author = { Id = 2, Name = "Author 2", DateOfBirth = DateTime.Now, DateOfDeath = DateTime.Now }, AuthorId = 2 }
};
mock.Setup(m => m.Books).Returns(books.AsQueryable());
var controller = new BooksController(mock.Object);
}
它看起来一切都很好。但是当我运行这个测试时:
[TestMethod]
public void IndexLoadsValid()
{
// Arrange
var controller = new BooksController(mock.Object);
// Act
var result = controller.Index() as ViewResult;
// Assert
Assert.IsNotNull(result);
}
我收到以下错误:
你调用的对象是空的
这很清楚。它是空的。但我不明白为什么它是空的?
调试说:
System.NullReferenceException: 'Object reference not set to an instance of an object.'
Assignment2.Models.Book.Author.get returned null.
这对我来说没有意义,因为当我启动程序时这个功能起作用。
Book
模型在这里:
public class Book
{
[Key]
public int Id { get; set; }
[Required]
public string Title { get; set; }
[Display(Name = "Publication date")]
public DateTime? PublicationDate { get; set; }
public float? Edition { get; set; } // We might have a 2.5 edition. Rare but happens
public int AuthorId { get; set; }
public Author Author { get; set; }
}
我不知道它是否有帮助,但我的ILibraryRepository
在这里:
public interface ILibraryRepository
{
IQueryable<Book> Books { get; }
IQueryable<Author> Authors { get; }
Book Save(Book book);
Author Save(Author author);
void Delete(Book book);
void Delete(Author author);
}
知道我为什么会收到这个错误吗?
编辑:我把HomeController
改为BooksController
。我不知道为什么我把这两个混在了一起。错误发生在[TestInitialize]
部分
您的初始化方法正好为零。基本上,您需要花费大量精力将模拟分配给初始化方法“var controller”中的临时局部变量,这是您在测试中未使用的。如果这还不够,它甚至是你的测试方法所使用的不同控制器。你需要做这样的事情:
private HomeController controller;
[TestInitialize]
public void TestInitialize()
{
mock = new Mock<ILibraryRepository>();
books = new List<Book>()
{
new Book { Id = 0, Title = "Title 0", Edition = 0, PublicationDate = DateTime.Now, Author = { Id = 0, Name = "Author 0", DateOfBirth = DateTime.Now, DateOfDeath = DateTime.Now }, AuthorId = 0 },
new Book { Id = 1, Title = "Title 1", Edition = 1, PublicationDate = DateTime.Now, Author = { Id = 1, Name = "Author 1", DateOfBirth = DateTime.Now, DateOfDeath = DateTime.Now }, AuthorId = 1 },
new Book { Id = 2, Title = "Title 2", Edition = 2, PublicationDate = DateTime.Now, Author = { Id = 2, Name = "Author 2", DateOfBirth = DateTime.Now, DateOfDeath = DateTime.Now }, AuthorId = 2 }
};
mock.Setup(m => m.Books).Returns(books.AsQueryable());
controller = new HomeController(mock.Object);
}
[TestMethod]
public void IndexLoadsValid()
{
// Arrange - use arrange from test initialise
// Act
var result = controller.Index() as ViewResult;
// Assert
Assert.IsNotNull(result);
}
并不是说这是最好的做法,但你需要实际使用初始化方法的结果,而不是让它被垃圾收集,如果你想让测试使用它。
您使用了Author = {Id = 0,etc},它假定Books构造函数也实例化了作者,但它仍为null。如果您需要有关例外的帮助,请包含堆栈跟踪
正如@PaulAbbott所说:
Author = { Id = 0...
应该是Author = new Author() { Id = 0...