Mark Cooper
Mark Cooper

Reputation: 6894

Mocking properties to test validation methods

I want to test a method that is validating that some application properties have been set. I'm trying to mock the call that fetches the settings:

public interface IMyLogic{
    string GetSetting(string key);
    bool AreSettingsValid(); 
}

public class MyLogic: IMyLogic {
    public string GetSetting(string key){
        return (string) Properties.Settings.Default[key];
    }

    public bool AreSettingsValid(){
        return GetSetting("Setting1") != null && GetSetting("Setting2") != null;
    }
}

[TestClass]
public class MyLogicTest {
    [TestMethod]
    public void MyLogic_AreSettingsValidIsTrue_WhenValuesAreSet(){
        var mockMyLogic = Mock<IMyLogic>();
        mockMyLogic.Setup(m=>m.GetSetting(It.IsAny<string>())).Returns("something");
        Assert(true, mockMyLogic.Object.AreSettingsValid());
    }
}

This is not working. How do I get AreSettingsValid() to trigger the mocked call to GetSetting?

Upvotes: 0

Views: 445

Answers (1)

Simply Ged
Simply Ged

Reputation: 8672

You need to use the IMyLogic in a different class to mock it and fake the output. For example:

class MyLogic
{
    bool AreSettingsValid(IMySettings mySettings){
        return mySettings.GetSetting("Setting1") != null &&
               mySettings.GetSetting("Setting2") != null;
    }
}

class MySettings: IMySettings {
    string GetSetting(string key){
        return (string) Properties.Settings.Default[key];
    }

}

[TestClass]
class MyLogicTest 
{
    [TestMethod]
    void MyLogic_AreSettingsValidIsTrue_WhenValuesAreSet(){
        var mockMySettings = Mock<IMySettings>();

        mockMySettings.Setup(m=>
            m.GetSetting(It.IsAny<string())).Returns("something");


        var myLogic = new MyLogic();

        Assert(true, myLogic.AreSettingsValid(mySettings.Object));
    }
}

You want to "mock" the interfaces that are used within your class under test, not the mock itself.

In the code above I have added a new class that represents the settings. Now I can mock the interface that class implements to mock what the GetSettings() call will do i.e. return the setting. I can now test the MyLogic class without having to rely on the Properties.Settings.Default[key] code as that relies on something external being present which you don't really want to rely on when doing unit tests.

Hope that helps?

Upvotes: 2

Related Questions