本文介绍了RhinoMocks:模拟属性 getter 的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 RhinoMocks 的新手,除了了解幕后发生的事情之外,还试图掌握语法.

I'm new to RhinoMocks, and trying to get a grasp on the syntax in addition to what is happening under the hood.

我有一个用户对象,我们将其命名为 User,它有一个名为 IsAdministrator 的属性.IsAdministrator 的值通过检查用户安全权限的另一个类进行评估,并根据这些权限返回 true 或 false.我试图模拟这个 User 类,并伪造 IsAdministrator 的返回值以隔离一些单元测试.

I have a user object, we'll call it User, which has a property called IsAdministrator. The value for IsAdministrator is evaluated via another class that checks the User's security permissions, and returns either true or false based on those permissions. I'm trying to mock this User class, and fake the return value for IsAdministrator in order to isolate some Unit Tests.

这是我目前所做的:

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

    // do something with my User object
} 

现在,我希望 Rhino 会伪造"对属性 getter 的调用,然后将 true 返回给我.这不正确吗?目前,由于 IsAdministrator 属性中的依赖关系,我收到了一个异常.

Now, I'm expecting that Rhino is going to 'fake' the call to the property getter, and just return true to me. Is this incorrect? Currently I'm getting an exception because of dependencies in the IsAdministrator property.

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

Can someone explain how I can achieve my goal here?

推荐答案

在我开始讨论之前的一个简短说明.通常,您希望避免使用严格"模拟,因为它会使测试变得脆弱.如果发生任何您没有明确告诉 Rhino 会发生的事情,严格模拟将抛出异常.此外,我认为您在调用创建模拟时可能会误解 Rhino 正在做什么.将其视为源自或实现您定义的 System.Type 的自定义对象.如果你自己做,它看起来像这样:

One quick note before I jump into this. Typically you want to avoid the use of a "Strict" mock because it makes for a brittle test. A strict mock will throw an exception if anything occurs that you do not explicitly tell Rhino will happen. Also I think you may be misunderstanding exactly what Rhino is doing when you make a call to create a mock. Think of it as a custom Object that has either been derived from, or implements the System.Type you defined. If you did it yourself it would look like this:

public class FakeUserType: User
{
    //overriding code here
}

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

Since IsAdministrator is probably just a public property on the User type you can't override it in the inheriting type.

就您的问题而言,您可以通过多种方式处理此问题.您可以将 IsAdministrator 实现为用户类上的虚拟属性,如 aaronjensen 提到如下:

As far as your question is concerned there are multiple ways you could handle this. You could implement IsAdministrator as a virtual property on your user class as aaronjensen mentioned as follows:

public class User
{
    public virtual Boolean IsAdministrator { get; set; }
}

这是一个不错的方法,但前提是您计划从您的 User 类继承.此外,如果您不想伪造此类中的其他成员,他们也必须是虚拟的,这可能不是您想要的行为.

This is an ok approach, but only if you plan on inheriting from your User class. Also if you wan't to fake other members on this class they would also have to be virtual, which is probably not the desired behavior.

实现此目的的另一种方法是使用接口.如果它确实是您想要 Mock 的 User 类,那么我会从中提取一个接口.你上面的例子看起来像这样:

Another way to accomplish this is through the use of interfaces. If it is truly the User class you are wanting to Mock then I would extract an interface from it. Your above example would look something like this:

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 而变得更有趣,但基本原则是一样的.通常,您希望您的类依赖于接口而不是具体的实现.

You can get fancier if you want by using dependency injection and IOC but the basic principle is the same across the board. Typically you want your classes to depend on interfaces rather than concrete implementations anyway.

我希望这会有所帮助.我已经在一个主要项目中使用 RhinoMocks 很长时间了,所以不要犹豫,问我关于 TDD 和 mocking 的问题.

I hope this helps. I have been using RhinoMocks for a long time on a major project now so don't hesitate to ask me questions about TDD and mocking.

这篇关于RhinoMocks:模拟属性 getter 的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-20 10:09