2012-02-16 2 views
1

Я попытался после этого в качестве руководства для Дразнящего реестра: http://www.rhyous.com/2011/11/04/unit-testing-registry-access-with-rhinomocks-and-systemwrapper/Дразнящего реестра - SystemWrapper

Когда я пытаюсь издеваться, я всегда получаю нулевой возврат к «REG» в моем классе, когда он пытается для выполнения вызова OpenSubKey в моем тесте _Real() он работает нормально.

Тесты:

private RegistryService CreateMockedRegistryService() 
{ 
    var registryService = new RegistryService(MockRepository.GenerateMock<ILoggerFacadeExtended>(), MockRepository.GenerateMock<IConnectivityService>()); 
    // Mock the Base Key so we can throw errors and manipulate it 
    registryService.ChangeBaseKey(MockRepository.GenerateMock<IRegistryKey>()); 
    return registryService; 
} 

private IRegistryKey CreateMockedHKLM() 
{ 
    IRegistryKey hklmMock = MockRepository.GenerateMock<IRegistryKey>(); 
    hklmMock.Stub(x => x.Name).Return("HKEY_LOCAL_MACHINE"); 
    return hklmMock; 
} 

[TestMethod()] 
public void GetRegistryKeyTest_Mocked() 
{ 
    IRegistryService target = CreateMockedRegistryService(); 
    string machineName = "localhost"; 
    RegistryHive hive = RegistryHive.LocalMachine; 
    string path = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion"; 
    string valueName = "SystemRoot"; 
    object defaultValue = @"C:\Windows"; 

    IRegistryKey keyMock = CreateMockedHKLM(); 
    keyMock.Stub(x => x.OpenRemoteBaseKey(hive, machineName)).Return(CreateMockedHKLM()); 
    var subKeyMock = MockRepository.GenerateMock<IRegistryKey>(); 
    subKeyMock.Stub(x => x.Name).Return(keyMock.Name + @"\" + path); 
    subKeyMock.Stub(x => x.GetValueNames()).Return(new string[] { valueName }); 
    subKeyMock.Stub(x => x.GetValue(valueName)).Return(defaultValue); 

    keyMock.Stub(x => x.OpenSubKey(path)).Return(subKeyMock); 
    keyMock.Stub(x => x.GetValue(valueName)).Return(defaultValue); 
    target.ChangeBaseKey(keyMock); 

    IResult<object> expected = new Result<object>() { Results = defaultValue }; 
    IResult<object> actual; 
    actual = target.GetRegistryKey(machineName, hive, path, valueName, defaultValue); 

    Assert.AreEqual(expected.Results, actual.Results); 
} 

[TestMethod()] 
public void GetRegistryKeyTest_Real() 
{ 
    IRegistryService target = CreateMockedRegistryService(); 
    string machineName = "localhost"; 
    RegistryHive hive = RegistryHive.LocalMachine; 
    string path = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion"; 
    string valueName = "SystemRoot"; 
    object defaultValue = @"C:\Windows"; 

    // We don't want to use the regular Mocked version but actually hit the registry so it works 
    IRegistryKey baseKey = new RegistryWrap().LocalMachine; 
    target.ChangeBaseKey(baseKey); 

    IResult<object> expected = new Result<object>() { Results = defaultValue }; 
    IResult<object> actual; 
    actual = target.GetRegistryKey(machineName, hive, path, valueName, defaultValue); 

    Assert.AreEqual(expected.Results, actual.Results); 
} 

Фактический класс:

private IRegistryKey _BaseKey; 
public IRegistryKey BaseKey 
{ 
    get 
    { 
     if (_BaseKey == null) 
     { 
      _BaseKey = new RegistryWrap().LocalMachine; 
     } 
     return _BaseKey; 
    } 
} 

public void ChangeBaseKey(IRegistryKey inBaseKey) 
{ 
    _BaseKey = inBaseKey; 
} 

public IResult<object> GetRegistryKey(string machineName, RegistryHive hive, string path, string valueName, object defaultValue) 
    { 
     return GetRegistryKey(BaseKey.OpenRemoteBaseKey(hive, machineName), path, valueName, defaultValue); 
    } 
} 

public IResult<object> GetRegistryKey(IRegistryKey baseKey, string path, string valueName, object defaultValue) 
{ 
    IResult<object> result = new Result<object>(); 
    try 
    { 
     if (baseKey == null) throw new ArgumentNullException("baseKey"); 
     if (string.IsNullOrWhiteSpace(path)) throw new ArgumentException("path"); 
     if (string.IsNullOrWhiteSpace(valueName)) throw new ArgumentException("valueName"); 
     var reg = baseKey.OpenSubKey(path); 
     result.Results = reg.GetValue(valueName); // reg is null when I try to Mock it 
    ..... 
    } 
} 

ответ

0

я понял это, я добавлял заглушки дела с OpenSubKey к исходному keyMock, а не тот, который был возвращен OpenRemoteBaseKey()

Вот фиксированный код:

[TestMethod()] 
public void GetRegistryKeyTest_Mocked() 
{ 
    IRegistryService target = CreateMockedRegistryService(); 
    string machineName = "localhost"; 
    RegistryHive hive = RegistryHive.LocalMachine; 
    string path = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion"; 
    string valueName = "SystemRoot"; 
    object defaultValue = @"C:\Windows"; 


    var keyMock = CreateMockedHKLM(); 
    var remoteKeyMock = CreateMockedHKLM(); 
    var subKeyMock = MockRepository.GenerateMock<IRegistryKey>(); 
    subKeyMock.Stub(x => x.Name).Return(keyMock.Name + @"\" + path); 
    subKeyMock.Stub(x => x.GetValueNames()).Return(new string[] { valueName }); 
    subKeyMock.Stub(x => x.GetValue(valueName)).Return(defaultValue); 
    remoteKeyMock.Stub(x => x.OpenSubKey(path)).Return(subKeyMock); 
    remoteKeyMock.Stub(x => x.GetValue(valueName)).Return(defaultValue); 

    keyMock.Stub(x => x.OpenRemoteBaseKey(hive, machineName)).Return(remoteKeyMock); 
    target.ChangeBaseKey(keyMock); 

    actual = target.GetRegistryKey(machineName, hive, path, valueName, defaultValue); 

    Assert.AreEqual(expected.Results, actual.Results); 
    subKeyMock.AssertWasCalled(x => x.GetValue(valueName)); 
} 
+0

Хорошо. Теперь спросите себя, что я тестирую? Похоже, вы тестируете макет, а не какую-либо реализацию, которая сделала бы его для производства. Ваше тестовое имя даже отражает это! Если вы «издеваетесь» на RepositoryService, вы должны проверить, работает ли он на других объектах (mocks), как и следовало ожидать (например, он вызывает «OpenRemoteBasekey»). В основном вы, похоже, сейчас стучите и проверяете, возвращает ли заглушка то, что вы его настроили, чтобы вернуться. – Joppe

+0

@ Тунгано, есть ли у вас лучший способ регистрации реестров устройств, не касаясь реестра? Он все еще проходит через код моего класса и дает мне результаты, которые я ищу ... разве это не то, что касается Mocks и Stubs? Я пытался заставить это работать весь день, поэтому, пожалуйста, дайте мне знать, если у вас есть лучший способ сделать это :) – John

+0

Если вы хотите протестировать какой-то код, зависящий от RegistryService, и не касаться фактического реестра: Stub методы GetRegistryKey. Вы можете использовать фальшивую инфраструктуру для этого, если оба метода являются виртуальными. Или создайте службу IRegistryService и используйте свою насмешливую структуру для создания заглушки с этим. Затем убедитесь, что вы можете получить проверенный код для использования вашего заглушки (предпочтительная инъекция зависимостей). – Joppe

Смежные вопросы