从同一方法模拟两个不同的结果

Mocking two different results from the same method

我有两种操作方法,编辑和删除(都是post)。这些方法从数据库接口调用方法。这些接口方法在一个名为DBManager 的class 中实现。在这些方法中,用户被编辑并返回布尔结果,删除方法也是如此,返回的结果将是 true 或 false,具体取决于删除或编辑是否成功。

现在我想模拟两个结果(真和假),这是我设置模拟的代码:

//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);`

这是我的测试代码

 [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");
    }

测试似乎只有在我单独 运行 时才能通过(运行 一个而另一个被注释掉)。我的问题是,有没有办法 运行 一次完成所有测试并让它们通过,记住我正在尝试测试两种不同的场景(真和假)。他们说假设是所有错误的魔鬼,现在我不能假设仅仅因为错误的结果似乎工作正常那么真实的结果也会是完美的

您没有给出最小起订量应 return 真或假的条件。只需将编辑用例的设置更改为:

_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);

此处显着的变化是使用 It.Is() 而不是您的 It.IsAny()。来自文档:

It.IsAny():

Matches any value of the given TValue type

It.Is():

Matches any value that satisfies the given predicate.

您可以使用 SetupReturns 中的函数,在调用模拟成员时根据提供的输入执行自定义逻辑。

_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
    });

您可以在 Func 中实现任何逻辑以满足您的测试的多种场景。

此外,如评论中所述,尝试为每个测试安排一次,以便设置在 运行 在一起时不会相互覆盖,因为成员的最后一个设置将覆盖任何先前匹配的设置。它简化了测试过程,因为每个 单元测试 应该是 运行 孤立的,并且不应受到列表中其他测试的影响。