Verifying that a mocked method have been called with Moq

[Test]
public void It_Should_Call_The_Number_Generator_Service()
{
    var result = _numbersProvider.GetNumbersCollection(10);
 
    //We are checking that the GetNumber()
    //method has been called exactely 10 times
    _numberGeneratorServiceMock.Verify(m => m.GetNumber(It.IsAny<int>(), It.IsAny<int>()),
        Times.Exactly(10));
 
    //We can also check that the mocked method
    //has been called with the desired parameters
    _numberGeneratorServiceMock.Verify(m => m.GetNumber(It.Is<int>(min => min == 1), It.Is<int>(max => max == 10)),
        Times.Exactly(10));
}

Is possible to reset the calls on a mock object by calling the ResetCalls() method. In this way is possible to test it again against a different condition.

Entity Framework Repository Test Example

Since we are using the Entity Framework’s context object as dependency we should consider this test as an integration test (unless we want to mock EF). Here is the test code:

public class PasswordEntryRepositoryTest
{
    [TestFixture]
    public class When_Password_Entry_Repository_Is_Present
    {
        private DbContext _context;
        private DbContextTransaction _transaction;
        private IRepository<PasswordEntry, string> _passwordEntryRepository;
 
        [SetUp]
        public void SetUp()
        {
            _context = new PasswordAPIContext();
            _transaction = _context.Database.BeginTransaction();
            _passwordEntryRepository = new PasswordEntryRepository(_context);
        }
 
        [Test]
        public void It_Should_Create_A_Password_Entry()
        {
            var item = new PasswordEntry
            {
                UserId = "user",
                Salt = "salt",
                PasswordHash = "passwordHash",
                Expiration = DateTime.Now
            };
            Assert.DoesNotThrow(() => _passwordEntryRepository.AddNew(item));
        }
 
        [Test]
        public void It_Should_Read_All_The_Password_Entries()
        {
            var item = new PasswordEntry
            {
                UserId = "user",
                Salt = "salt",
                PasswordHash = "passwordHash",
                Expiration = DateTime.Now
            };
            _passwordEntryRepository.AddNew(item);
            Assert.IsTrue(_passwordEntryRepository.GetAll().Any());
        }
 
        [Test]
        public void It_Should_Read_A_Password_Entry_By_User()
        {
            var item = new PasswordEntry
            {
                UserId = "user",
                Salt = "salt",
                PasswordHash = "passwordHash",
                Expiration = DateTime.Now
            };
            _passwordEntryRepository.AddNew(item);
            var dbItem = _passwordEntryRepository.GetById("user");
            Assert.AreEqual(item.UserId, dbItem.UserId);
        }
 
        [Test]
        public void It_Should_Update_A_Password_Entry()
        {
            var item = new PasswordEntry
            {
                UserId = "user",
                Salt = "salt",
                PasswordHash = "passwordHash",
                Expiration = DateTime.Now
            };
            _passwordEntryRepository.AddNew(item);
            item.Salt = "saltUpdated";
            _passwordEntryRepository.Update(item);
            var dbItem = _passwordEntryRepository.GetById("user");
            Assert.AreEqual(item.Salt, dbItem.Salt);
        }
 
        [Test]
        public void It_Should_Delete_A_Password_Entry()
        {
            var item = new PasswordEntry
            {
                UserId = "user",
                Salt = "salt",
                PasswordHash = "passwordHash",
                Expiration = DateTime.Now
            };
            _passwordEntryRepository.AddNew(item);
            _passwordEntryRepository.Delete(item.UserId);
            var dbItem = _passwordEntryRepository.GetById("user");
            Assert.IsNull(dbItem);
        }
 
        [TearDown]
        public void TearDown()
        {
            _transaction.Rollback();
            _transaction.Dispose();
            _context.Dispose();
        }
    }
}

Testing with NUnit

To use the NUnit testing framework within a .Net project we have to create a normal Class Library Project (not a Unit Test Project, that is for the UnitTest Framework). Then we can add NUnit to the project via NuGet to start writing tests.

To write a test we have to create a class in the same way we do with UnitTest. NUnit offers some interesting functionality, such as the SetUp/TearDown methods, executed before/after each test, the possibility to have parametrized methods, and so on.

Here is an example in which we are testing an object who represent a range between two points and calculate its length:

//Additional NS
using NUnit.Framework;
using ProvaNUnit;
 
namespace MyTestLibrary
{
    public class MyRangeModelTest
    {
        [TestFixture]
        public class Given_A_MyRangeModel
        {
            private MyRangeModel _model;
 
            //The SetUp method will be
            //executed before each test
            [SetUp]
            public void SetUp()
            {
                _model = new MyRangeModel
                {
                    Point1 = 2,
                    Point2 = 10
                };
            }
 
            //This is a test
            [Test]
            public void It_Should_Calculate_The_Length()
            {
                Assert.AreEqual(_model.RangeLength, 8);
            }
 
            //This is a parametrized test. It will
            //be executed for each parameters set
            [Test]
            [TestCase(3, 8, TestName = "With_A_Forward_Range")]
            [TestCase(8, 3, TestName = "With_A_Backward_Range")]
            [TestCase(5, 5, TestName = "With_A_Empty_Range")]
            public void It_Should_Calculate_More_Lengths(int point1, int point2)
            {
                _model.Point1 = point1;
                _model.Point2 = point2;
 
                Assert.AreEqual(_model.RangeLength, Math.Abs(point2 - point1));
            }
 
            //The TearDown method will be
            //executed after each test
            [TearDown]
            public void TearDown()
            {
                _model = null;
            }
        }
    }
}

I can run NUnit tests directly from VS with Resharper. I can run a single test or the entire test set by right-clicking on the text editor. The results will be displayed in both the text editor and the Resharper Unit Test window.