Home > Mobile >  NUnit Setup Method not using new values handed in
NUnit Setup Method not using new values handed in

Time:09-05

I'm trying to get better with TDD and implement some unit tests using NUnit for a desk booking application. My Setup is as follows...

[SetUp]
public void Setup()
{
    deskBookingRequest = new DeskBookingRequest
    {
        FirstName = "Alex",
        LastName = "Barry",
        Email = "[email protected]",
        Date = new DateTime(2022, 8, 28)
    };

    availableDesks = new List<Desk>() { new Desk() };
    _databaseService.Setup(x => x.GetDesks(It.IsAny<DateTime>())).Returns(availableDesks);
}

I'm trying to create a scenario in which the .GetDesks method would return null which would cause the .Save method to never be called. I figured I could do something like the following (in where the .GetDesks is called within .BookDesk...

[Test]
public void ShouldNotSaveDeskIfNoneAreAvailable()
{
    //Arrange
    availableDesks = null;

    //Act
    result = _processor.BookDesk(deskBookingRequest);

    //Assert
    _databaseService.Verify(x => x.Save(It.IsAny<DatabaseSaveBookingRequest>()), Times.Never);
}

but .GetDesks is still returns a List with one desk object. Would I need to specifically call a new setup method for .GetDesks or is there a way to achieve what I'm trying to do here?

CodePudding user response:

[Setup]-annotated methods run before each test method, so it already sets up the _databaseService with the availableDesks object. Even when you later null out availableDesks in the test, the _databaseService has a reference to the original object.

Do yourself the favour and forgo the use of setup methods. They cause all sorts of aliasing problems like the one you are encountering. Instead, write self-contained test methods like this:

[Test]
public void ShouldNotSaveDeskIfNoneAreAvailable()
{
    //Arrange
    // ...
    databaseService.Setup(x => x.GetDesks(It.IsAny<DateTime>())).Returns(null);
    // ...

    //Act
    result = processor.BookDesk(deskBookingRequest);

    //Assert
    databaseService.Verify(
        x => x.Save(It.IsAny<DatabaseSaveBookingRequest>()),
        Times.Never);
}

Don't use class fields, but create object within the test methods.

If you are concerned about code duplication, address that concern like you would in any other code base. If you need inspiration or examples, there's literally an entire book about unit test patterns.

  • Related