Mocking two different results using the same method

I have two action methods, edit and delete (both posts). These methods call methods from the DB interface. This interface method is implemented in a class called DBManager

. In these methods, the user receives the edit and returns boolean results, the same applies to the delete method, the return result will be either true or false, depending on whether the delete or edit was successful.

Now I want to mock two results (true and false), here is my code where I set up the mocks:

//setup passed test
_moqDB.Setup(md => md.EditStaff(It.IsAny<StaffEditViewModel>())).Returns(true);

//setup failed test
_moqDB.Setup(md => md.EditStaff(It.IsAny<StaffEditViewModel>())).Returns(false);

//Setup Delete method test
_moqDB.Setup(x => x.DeleteStaffMember(It.IsAny<int>())).Returns(true);

//delete failed
_moqDB.Setup(x => x.DeleteStaffMember(It.IsAny<int>())).Returns(false);`

      

Here is my test code

 [TestMethod]
    public void PostUpdatedUserTest()
    {
        var staffEdit = new StaffEditViewModel()
        {
            BranchID = "HQ",
            SiteID = "TestingSite",
            StaffEmail = "Zandile.Mashele@avisbudget.co.za",
            StaffID = 887,
            StaffNameF = "TestUser",
            StaffNameS = "TestSurname",
            StaffPassword = "****",
            StaffSecurity = UserRoles.Administrator
        };

        //Act
        var result = _userController.Edit(staffEdit);

        //Assert
        Assert.IsNotNull(result);
        Assert.IsInstanceOfType(result, typeof(RedirectToRouteResult));
        var redirectResult = result as RedirectToRouteResult;
        Assert.AreEqual("Index", redirectResult.RouteValues["action"]);
    }

    [TestMethod]
    public void PostUpdatedUserFailTest()
    {
        var staffEdit = new StaffEditViewModel()
        {
            BranchID = "HQ",
            SiteID = "TestSite",
            StaffEmail = "Zandile.Mashele@avisbudget.co.za",
            StaffID = 1,
            StaffNameF = "Test1",
            StaffNameS = "TestSurname",
            StaffPassword = "****",
            StaffSecurity = UserRoles.Administrator
        };

        //Act
        var result = _userController.Edit(staffEdit) as ViewResult;

        // Assert
        Assert.IsNotNull(result);
        Assert.IsTrue(string.IsNullOrEmpty(result.ViewName) || result.ViewName == "Error");
    }

      

The tests only seem to pass when I run them individually (run it and the other is commented out). My question is if there is a way to run these tests right away and pass them, remember that I am trying to test two different scenarios (true and false). They say that the assumption is the hell of all mistakes, now I can't guess because the false result seems to work fine, then the true result will be perfect too.

+3


source to share


2 answers


You can use a function in Returns

Setup

to execute custom logic based on the provided input when the mocked element is called.

_moqDB
    .Setup(_ => _.EditStaff(It.IsAny<StaffEditViewModel>()))
    .Returns((StaffEditViewModel arg) => {
        if(arg != null && arg.StaffID == 887) return true;
        else return false; //this will satisfy other Ids like 1
    });

_moqDB
    .Setup(_ => _.DeleteStaffMember(It.IsAny<int>()))
    .Returns((int staffId) => {
        if(staffId == 887) return true;
        else return false; //this will satisfy other Ids like 1
    });

      



You can implement logic in Func

to execute multiple scripts for your tests.

Also, as mentioned in the comments, try positioning once per test so the settings don't override each other when run together, as the last setting on the member will override any previous settings that match. This simplifies this testing process as each unit test should be run in isolation and should not be affected by other tests in the list.

+2


source


You haven't given any conditions for when Moq should return true or false. Just change your use case setting like:

_moqDB.Setup(md => md.EditStaff(It.Is<StaffEditViewModel>(x => x.StaffID == 887))).Returns(true);

_moqDB.Setup(md => md.EditStaff(It.Is<StaffEditViewModel>(x => x.StaffID == 1))).Returns(false);

      

The notable change here is to use It.Is()

instead of yours It.IsAny()

. From the documentation:

It.IsAny()

:



Matches any value of the given TValue type

It.Is()

:

Matches any value that satisfies the specified predicate.

+2


source







All Articles