0

I'm trying to run some unit tests and I need to do the [TestInitialize] thing.

I found some info in this post. I have no idea how to fix it because it makes no sense to me.

[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);
}

It looks all good and fine. But when I run this test:

[TestMethod]
public void IndexLoadsValid()
{
    // Arrange
    var controller = new BooksController(mock.Object);

    // Act
    var result = controller.Index() as ViewResult;

    // Assert
    Assert.IsNotNull(result);
}

I get the following error:

object reference not set to an instance of an object

And this is clear. It's null. But what I don't understand is why it's null?

The debugging says:

System.NullReferenceException: 'Object reference not set to an instance of an object.'

Assignment2.Models.Book.Author.get returned null.

And this makes no sense to me because this function works when I fire up the program.

The Book model is here:

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; }
}

I have no idea if it helps but my ILibraryRepository is here:

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);
}

Any idea why I'm getting this error?

EDIT: I changed the HomeController to BooksController. I have no idea why I mixed the two here. The error is happening in the [TestInitialize] part

Alex Ironside
  • 4,658
  • 11
  • 59
  • 119

3 Answers3

1

Your initialise method is doing precisely zero. Basically, you're going to a lot of effort to assign a mock to a temporary local variable in the initialise method "var controller", that you aren't using in your test. And if that wasn't enough, its even a different controller that your test method is using. You'd need to do something like this:

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);
}

Not that this is necessarily best practice, but you need to actually do something with the result of the initialise method other than let it be garbage collected if you want the test to use that.

Adam Brown
  • 1,667
  • 7
  • 9
  • Thanks for catching that. I edited the post but the same error persists. The error is happening in the `[TestInitialize]` part – Alex Ironside Dec 22 '17 at 01:06
  • It will be in the use part of the code, not in the test code. I can't see any reason in the test code why this happens. Perhaps the code in the controller has additional dependencies that aren't being initialised by your test code. What is Assignment2, and is it being called directly, statically, from your controller constructor? – Adam Brown Dec 22 '17 at 01:23
  • It got solved in the comments. Thanks for the help though! – Alex Ironside Dec 22 '17 at 01:36
0

You used Author = { Id=0 , etc} , that assumes the Books constructor also instantiates the author however it is still null. Please include a stacktrace if you need help with an exception

Robbert Draaisma
  • 463
  • 4
  • 14
0

As @PaulAbbott said:

Author = { Id = 0... should have been Author = new Author() { Id = 0...

Alex Ironside
  • 4,658
  • 11
  • 59
  • 119