mithun_daa
mithun_daa

Reputation: 4384

Check if a property was set - using Moq

I am new to Moq and testing in general so here is my noobish Q. How do I test if the Status property on Request has been set using Moq?

public class DudeManager
{
        private readonly IDRepository _repo;

        public DManager(IDRepository repo)
        {
            _repo = repo;
        }

        public void Create(Request r)
        {
            r.Status = Status.Submitted;
            _repo.AddRequest(r);
        }
}

Is there a better approach than the following? Maybe using VerifySet?

        [TestMethod]
        public void AddingNewRequestSetsStatusToSubmitted()
        {
            //Arrange
            var mock = new Mock<IDRepository>();
            var mockRequest = new Mock<Request>();
            var dManager = new DManager(mock.Object);

            //Act
            dManager.Create(mockRequest.Object);

            //Assert
            Assert.AreEqual(Status.Submitted, mockRequest.Object.Status);
        }

EDIT: This is the approach I ended up using after all the helpful suggestions:

//Arrange
var request = new Request();
var mock = new Mock<IDRepository>();
var dManager = new DManager(mock.Object);
mock.Setup(x => x.AddRequest(It.IsAny<Request>()));

//Act
dManager.QueueNewRequest(request);

//Assert
Assert.AreEqual(RequestStatus.Submitted, request.Status);

This approach seems right to me. Does anyone think otherwise?

Upvotes: 23

Views: 28901

Answers (3)

AD.Net
AD.Net

Reputation: 13409

mock.Verify(m=>m.AddRequest(It.Is<Request>(r=>r.Status == expectedStatus)));

You can verify that the AddRequest method gets called with parameter (Request) which has the correct Status. Also, mocking the Request object is not really necessary here.

Upvotes: 4

Ufuk Hacıoğulları
Ufuk Hacıoğulları

Reputation: 38488

I think you should use strict behavior by default, then you can make the verification with a single call. It also makes you write your test more explicitly.

[TestMethod]
public void AddingNewRequestSetsStatusToSubmitted()
{
    //Arrange
    var mock = new Mock<IDRepository>(MockBehavior.Strict);
    var mockRequest = new Mock<Request>(MockBehavior.Strict);
    var dManager = new DManager(mock.Object);

    mockRequest.SetupSet(item => item.Status = It.IsAny<StatusType>())
               .Verifiable();

    //Act
    dManager.Create(mockRequest.Object);

    //Assert
    Assert.AreEqual(mockRequest.Object.Status, Status.Submitted);
    mock.VerifyAll();
    mockRequest.VerifyAll();
}

Upvotes: 7

neontapir
neontapir

Reputation: 4736

I think VerifySet is the right approach. It would look something like this:

//Arrange
var mock = new Mock<IDRepository>();
var mockRequest = new Mock<Request>();
// TODO: set some expectations here

var dManager = new DManager(mock.Object);

//Act
dManager.Create(mockRequest.Object);

//Assert
mockRequest.VerifySet(x => x.Status = Status.Submitted);

I believe in your case, it blows up because you haven't set up your Request mock to handle the set operation on Status.

One easy way to do that is using SetupAllProperties, like so:

//Arrange
var mock = new Mock<IDRepository>();
var mockRequest = new Mock<Request>();
mockRequest.SetupAllProperties();

Upvotes: 39

Related Questions