Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In a unit test, do you verify and assert?

I am using Moq in my unit test project. Most unit test examples I've seen online end with someMock.VerifyAll(); I wonder if it is OK to assert after VerifyAll(). So for example,

//Arrange
var student = new Student{Id = 0, Name="John Doe", IsRegistered = false};
var studentRepository = new Mock<IStudentRepository>();
var studentService= new StudentService(studentRepository.Object);

//Act
studentService.Register(student);  //<-- student.IsRegistered = true now.

//Verify and assert
studentRepository.VerifyAll();
Assert.IsTrue(student.IsRegistered);

Any thought? Thank you.

like image 262
Stack0verflow Avatar asked Dec 31 '13 21:12

Stack0verflow


People also ask

How do you assert in unit testing?

Assert the exact desired behavior; avoid overly precise or overly loose conditions. One assertion, one condition. Don't aggregate multiple checks in one assertion. Write assertions that check requirements, not implementation details of the unit under test.

What should a unit test include?

A unit test typically features three different phases: Arrange, Act, and Assert (sometimes referred to as AAA). For a unit test to be successful, the resulting behavior in all three phases must be in line with expectations.

Should a unit test only have one assert?

And usually, one test method only has one assert at the end of it. But what happens if you have multiple asserts in a unit test? If you have more than one assert in a unit test, the unit test will be completed successfully if all assertions are met.

How many assertions should a unit test contain?

One Assertion in One Test Method To keep unit tests simple, it is best to include a single assertion in one test method. That means, one unit test should test one use-case and no more.


2 Answers

No you should not use both together in most cases(there are always exceptions). The reason for that is you should be testing only one thing in your test for maintainability, readability and few other reasons. So it should be either Verify(VerifyAll) or Assert in your test and you name your tests accordingly.

Look at Roy Osherove's article about it:

http://osherove.com/blog/2005/4/3/a-unit-test-should-test-only-one-thing.html

VerifyAll is used to make sure certain methods are called and how many times. You use mocks for that.

Assert is used for verifying the result returned from the method you are testing. You use Stubs for that.

Martin fowler has a great article explaining the difference between mocks and stubs. If you understand it you will know the difference better.

http://martinfowler.com/articles/mocksArentStubs.html

UPDATE: example of mock vs stub using Moq as requested in the comment below. I have used Verify but you can use VerifyAll as well.

using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
... 

[TestClass]
public class UnitTest1
{
    /// <summary>
    /// Test using Mock to Verify that GetNameWithPrefix method calls 
    /// Repository GetName method once when Id is greater than Zero
    /// </summary>
    [TestMethod]
    public void GetNameWithPrefix_IdIsTwelve_GetNameCalledOnce()
    {
        // Arrange 
        var mockEntityRepository = new Mock<IEntityRepository>();
        mockEntityRepository.Setup(m => m.GetName(It.IsAny<int>()));

        var entity = new EntityClass(mockEntityRepository.Object);
        // Act 
        var name = entity.GetNameWithPrefix(12);
        // Assert
        mockEntityRepository.Verify(
            m => m.GetName(It.IsAny<int>()), Times.Once);
    }

    /// <summary>
    /// Test using Mock to Verify that GetNameWithPrefix method 
    /// doesn't calls Repository GetName method when Id is Zero
    /// </summary>
    [TestMethod]
    public void GetNameWithPrefix_IdIsZero_GetNameNeverCalled()
    {
        // Arrange 
        var mockEntityRepository = new Mock<IEntityRepository>();
        mockEntityRepository.Setup(m => m.GetName(It.IsAny<int>()));
        var entity = new EntityClass(mockEntityRepository.Object);
        // Act 
        var name = entity.GetNameWithPrefix(0);
        // Assert
        mockEntityRepository.Verify(
            m => m.GetName(It.IsAny<int>()), Times.Never);
    }

    /// <summary>
    /// Test using Stub to Verify that GetNameWithPrefix method
    /// returns Name with a Prefix
    /// </summary>
    [TestMethod]
    public void GetNameWithPrefix_IdIsTwelve_ReturnsNameWithPrefix()
    {
        // Arrange 
        var stubEntityRepository = new Mock<IEntityRepository>();
        stubEntityRepository.Setup(m => m.GetName(It.IsAny<int>()))
            .Returns("Stub");
        const string EXPECTED_NAME_WITH_PREFIX = "Mr. Stub";
        var entity = new EntityClass(stubEntityRepository.Object);
        // Act 
        var name = entity.GetNameWithPrefix(12);
        // Assert
        Assert.AreEqual(EXPECTED_NAME_WITH_PREFIX, name);
    }
}

public class EntityClass
{
    private IEntityRepository _entityRepository;
    public EntityClass(IEntityRepository entityRepository)
    {
        this._entityRepository = entityRepository;
    }
    public string Name { get; set; }
    public string GetNameWithPrefix(int id)
    {
        string name = string.Empty;
        if (id > 0)
        {
            name = this._entityRepository.GetName(id);
        }
        return "Mr. " + name;
    }
}

public interface IEntityRepository
{
    string GetName(int id);
}

public class EntityRepository:IEntityRepository
{
    public string GetName(int id)
    {
        // Code to connect to DB and get name based on Id
        return "NameFromDb";
    }
}
like image 115
Adarsh Shah Avatar answered Oct 03 '22 22:10

Adarsh Shah


Yes you should call the assert.

VerifyAll() will assert that all SetUp() calls were actually called.

VerifyAll() will not confirm that your student object is registered. Because there are no SetUp() calls in your test case, I think VerifyAll() isn't verifying anything.

like image 38
mmilleruva Avatar answered Oct 03 '22 20:10

mmilleruva