关于tdd:RhinoMocks:模拟属性获取器的正确方法

关于tdd:RhinoMocks:模拟属性获取器的正确方法

RhinoMocks: Correct way to mock property getter

我是RhinoMocks的新手,除了了解引擎盖下发生的事情之外,还尝试掌握语法。

我有一个用户对象,我们将其称为User,它具有名为IsAdministrator的属性。 IsAdministrator的值是通过另一个检查用户安全权限的类评估的,并根据这些权限返回true或false。 我正在尝试模拟此User类,并假冒IsAdministrator的返回值以隔离某些单元测试。

到目前为止,这是我正在做的事情:

1
2
3
4
5
6
7
public void CreateSomethingIfUserHasAdminPermissions()
{
    User user = _mocks.StrictMock<User>();
    SetupResult.For(user.IsAdministrator).Return(true);

    // do something with my User object
}

现在,我期望Rhino可以"伪造"对属性获取器的调用,然后将true返回给我。 这不正确吗? 目前,由于IsAdministrator属性中的依赖性,我遇到了异常。

有人可以在这里解释我如何实现我的目标吗?


在我跳到此之前,请快速注意一下。通常,您要避免使用"严格"模拟,因为它会使测试变脆。如果发生任何未明确告知Rhino会发生的事件,则严格的模拟将引发异常。另外,我认为您打电话创建模拟游戏时可能会误解Rhino的行为。可以将其视为自定义对象的派生对象,或实现您定义的System.Type。如果您自己进行操作,则将如下所示:

1
2
3
4
public class FakeUserType: User
{
    //overriding code here
}

由于IsAdministrator可能只是User类型的公共属性,因此您不能在继承类型中覆盖它。

就您的问题而言,有多种方法可以解决此问题。您可以将IsAdministrator实现为用户类上的虚拟属性,如aaronjensen所述,如下所示:

1
2
3
4
public class User
{
    public virtual Boolean IsAdministrator { get; set; }
}

这是一种不错的方法,但前提是您打算从User类继承。同样,如果您不想在该类上伪造其他成员,那么他们也必须是虚拟的,这可能不是您想要的行为。

实现此目的的另一种方法是通过使用接口。如果确实是您要模拟的User类,那么我将从中提取一个接口。您上面的示例如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public interface IUser
{
    Boolean IsAdministrator { get; }
}

public class User : IUser
{
    private UserSecurity _userSecurity = new UserSecurity();

    public Boolean IsAdministrator
    {
        get { return _userSecurity.HasAccess("AdminPermissions"); }
    }
}

public void CreateSomethingIfUserHasAdminPermissions()
{
    IUser user = _mocks.StrictMock<IUser>();
    SetupResult.For(user.IsAdministrator).Return(true);

    // do something with my User object
}

如果需要,可以通过使用依赖项注入和IOC来获得更高的要求,但是基本原理是完全相同的。通常,无论如何,您都希望类依赖于接口而不是具体的实现。

我希望这有帮助。我已经在一个大型项目上使用RhinoMocks很长时间了,所以请随时向我询问有关TDD和模拟的问题。


确保IsAdministrator是虚拟的。

另外,请确保您调用_mocks.ReplayAll()


_mocks.ReplayAll()将不执行任何操作。只是因为您使用的是SetupResult.For()而不算在内。使用Expect.Call()确保代码正确无误。


推荐阅读

    linux命令所有用户?

    linux命令所有用户?,系统,密码,信息,情况,名称,命令,用户,时间,地址,位置,如

    linux命令进入用户?

    linux命令进入用户?,系统,密码,用户,地址,信息,软件,命令,用户名,联系方式,

    linux命令用户管理?

    linux命令用户管理?,系统,密码,管理,工作,信息,地址,工具,命令,用户,基础,LIn

    linux用户与组的命令?

    linux用户与组的命令?,管理,系统,名称,用户组,密码,用户,命令,情况,信息,单

    linux添加用户的命令?

    linux添加用户的命令?,密码,系统,软件,联系方式,用户,新增,信息,管理人员,

    linux看系统用户命令?

    linux看系统用户命令?,系统,信息,密码,命令,服务,名称,网络,情况,软件,工具,L

    linux赋权用户命令?

    linux赋权用户命令?,系统,密码,用户,权限,地址,状态,数字,软件,管理,电脑,Lin

    linux命令中添加用户?

    linux命令中添加用户?,系统,密码,软件,用户,命令,信息,目录,用户名,账号,文

    linux命令更改用户?

    linux命令更改用户?,系统,密码,管理,用户,命令,环境,工作,地址,电脑,文件,lin

    linux修改用户名命令?

    linux修改用户名命令?,系统,密码,查询系统,代码,数字,用户名,命令,第三,电

    linux命令给用户授权?

    linux命令给用户授权?,系统,数字,管理,权限,命令,密码,工具,时间,软件,信息,l

    linux命令创建用户组?

    linux命令创建用户组?,系统,代码,密码,用户组,用户,命令,信息,名称,新增,管

    linux命令给用户授权?

    linux命令给用户授权?,系统,数字,管理,权限,命令,密码,工具,时间,软件,信息,l

    linux命令创建用户组?

    linux命令创建用户组?,系统,代码,密码,用户组,用户,命令,信息,名称,新增,管

    linux模拟请求命令?

    linux模拟请求命令?,地址,工作,系统,工具,信息,标准,命令,目录,发行,数据,lin

    查看linux用户命令行?

    查看linux用户命令行?,信息,系统,时间,名称,密码,用户,命令,地址,状态,设备,L

    linux所有用户命令行?

    linux所有用户命令行?,系统,信息,地址,工作,密码,命令,用户,时间,电脑,管理,L

    linux用户下的命令是?

    linux用户下的命令是?,系统,工作,管理,地址,命令,密码,基础,信息,目录,新增,L

    linux用户登录的命令?

    linux用户登录的命令?,系统,信息,工作,地址,时间,密码,名称,命令,电脑,软件,l