2010-12-23 86 views
2

我已经使用Rhino Mocks编写了一些单元测试,除了事实上我不得不将底层Web服务公开为虚拟(isUserInRoleWebService)这一事实,因为这是我在部分模拟中的存根(stub) 。 我通常使用反射来避免暴露私有方法,但这不适用于模拟对象。 有没有人知道这个?必须是常见的情况。犀牛模拟部分存根必须是公共方法?

[SetUp] 
public void SetUp() 
{ 
    _mockRepository = new MockRepository(); 
    _entitlementCache = _mockRepository.PartialMock<EntitlementCache>(); 
} 

[Test] 
// simple test to verify membership of a single role 
public void Test_SingleRoleMember() 
{ 
    (new ReflectedObject(_entitlementCache)).InvokeInstanceMethod(
               "setRoleHierachy", 
               new object[] { hierachy2Level } 
              ); 

    using (_mockRepository.Record()) 
    { 
     // I had to convert isUserInRoleWebService to public :-(
     _entitlementCache.Stub(x => x.isUserInRoleWebService("user", "Role 1")) 
         .Repeat 
         .Once() 
         .Return(true); 
    } 

    using (_mockRepository.Playback()) 
    { 
     bool res = _entitlementCache.IsUserInRole("user", "Role 1"); 
     Assert.AreEqual(true, res, "user member of 'Role 1'"); 
    } 
} 

[TearDown] 
public void TearDown() 
{ 
    _mockRepository.ReplayAll(); 
    _mockRepository.VerifyAll(); 
} 

回答

1

通常,我不测试或模拟私有方法。看起来在这种情况下,您可能会更好地使Web服务本身作为缓存中的属性提供,然后模拟它。例如:

IWebService service = ... 
service.Expect(s => s.IsUserInRoleWebService("user", "Role 1")).Return(true); 

EntitlementCache cache = ... 
cache.Service = service; 

bool result = cache.IsUserInRole("user", "Role 1"); 
Assert.IsTrue(result, "user member of 'Role 1'"); 
3

您可以使用部分模拟考试覆盖protected internal virtual方法。请注意,您需要在被测项目的AssemblyInfo.cs中指定[InternalsVisibleTo("YourTestProject")]

protected internal(或protected internal,如果您愿意的话)是protectedinternal的联合。因此,internal + [InternalsVisibleTo]使该方法对您的测试项目可见,并且protected允许Rhino覆盖virtual方法。