用相同的方法模拟两个不同的结果

时间:2017-05-26 06:52:39

标签: c# unit-testing mocking moq

我有两个动作方法,编辑和删除(两个帖子)。这些方法从DB接口调用方法。这些接口方法在名为DBManager的类中实现。在这些方法中,用户被编辑并返回布尔结果,对于delete方法也是如此,返回的结果将为true或false,具体取决于删除或编辑是否成功。

现在我想模拟两个结果(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");
    }

测试似乎只在我单独运行时运行(运行一个而另一个被注释掉)。我的问题是,是否有一种方法可以同时运行这些测试并让它们通过,记住我正在尝试测试两种不同的场景(真和假)。他们说假设是所有错误的魔鬼,现在我不能假设只是因为错误的结果似乎工作正常然后真正的结果将是完美的

2 个答案:

答案 0 :(得分:3)

当Moq应该返回true或false时,你没有给出任何条件。只需将编辑用例的设置更改为:

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

  

匹配给定TValue类型的任何值

It.Is()

  

匹配满足给定谓词的任何值。

答案 1 :(得分:3)

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

Setup

您可以在_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 }); 中实现逻辑,以满足测试的多种情况。

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