3

When we unit test we often need to change some Sitecore configuration for the tests. For example, we may have the following:

<sitecore>
  <configuration>
    <someNode name="myService">http://myservice:1234/endpoint</someNode>
    <settings>
      <setting name="mySftp" value="sftp://mysftp:21/" />
    </settings>
  </configuration>
</sitecore>

and we may need to change it to the following when running our unit tests:

<sitecore>
  <configuration>
    <someNode name="myservice">http://test.myservice:1234/endpoint</someNode>
    <settings>
      <setting name="mySftp" value="sftp://test.mysftp:21/" />
    </settings>
  </configuration>
</sitecore>

I had previously been handling these changes by using different build configurations with config transforms. The problem with this is that I prefer to run my unit tests across both DEBUG and RELEASE mode, since the optimizations when building in RELEASE mode (shouldn't but) can cause errors in some code. I could work around this by customizing my targets and making two build configurations for unit tests, unitdebug and unitrelease, but this seems kind of hacky and I'm sure there are better solutions out there.

I'm wondering what techniques other people are using for handling these changes when running unit tests.

Note: Partial answers are totally acceptable for this one. I expect that there may be different techniques for different kinds of settings. Getting a bunch of ideas together that I and others can pick and choose from will make a great reference for the community! Of course, I will accept the answer that works best in the most cases :)

  • 1
    For simple settings you can use fakeDb.Configuration.Settings["SettingName"] = "NewValue"; in test code. – Alan Płócieniak Nov 30 '16 at 15:22
  • Add that as an answer so we can upvote :) – Zachary Kniebel Nov 30 '16 at 15:25
3

Assuming that you are using FakeDB for your Unit Tests you can simply change settings on the fly.

See example:

using (Db fakeDb = new Db())
{
    fakeDb.Configuration.Settings["SettingName"] = "SettingValue";
}

More info here.

  • Very cool! I haven't actually started using fakeDb in my unit tests, but I have been reading up on it and learning what I can so that I can POC it before my next project. +1 – Zachary Kniebel Nov 30 '16 at 19:00
6

I abstract out the configuration in to one (usually one but could more if it's a large project) Class with a corresponding Interface. Then rather than changing the config - I inject a mocked Interface with the config defined so that the unit test tests the functionality I'm after.

E.g.

public class ModuleConfiguration : IModuleConfiguration
    {
        public string MySetting
        {
            get
            {
                return Settings.GetSetting("MySetting",
                    "MyDefaultValue");
            }
        }

I try my hardest not to muddy the water with Sitecore API functionality mixed in with other functional stuff so I'd have some sort of manager class to abstract away any Sitecore specific functionality and then probably not worry too much about Unit testing Sitecore API stuff specifically.

In the past, when I've wanted to do integration tests with specific Sitecore API functionality - I've used an approach similar to this one where you use app.config to define the configuration for the tests to run. That allows you to have separate config for your tests compared to your Website project.

  • I like it - that's pretty similar o what I have been using lately for Settings (I'll post in a minute). The approach you linked to is also interesting. I'm going to have to try that one. Thanks :) – Zachary Kniebel Nov 30 '16 at 15:33
2

Recently, I have started using the SettingsSwitcher for mocking Sitecore <setting> values. I configure all of the mocked values in the constructor of a TestRunner class that I initialize before running any unit tests. The class is an IDisposable that I dispose of after the tests complete.

Using the example in the OP, the setting[@name='mySftp'] has the value sftp://mysftp:21/ but when unit testing this value should be changed to sftp://test.mysftp:21/. In order to do this, I would do the following:

public class TestRunner : IDisposable
{
    private SettingsSwitcher _settingsSwitcher;    

    public TestRunner()
    {
        _settingsSwitcher = new SettingsSwitcher("mySftp", "sftp://test.mysftp:21/");

        // ...continue calling SettingsSwitcher constructor for additional settings...

        // note that you don't have to keep setting the value of _settingsSwitcher after it has been initialized once
        new SettingsSwitcher("settingName", "settingTestValue");
    }

    public void Dispose() 
    {
        if (_settingsSwitcher != null) 
        {
            _settingsSwitcher.Dispose();   
        }
    }
}  

Unfortunately, this approach doesn't work for other Sitecore config node types, including custom ones, but it works well for the settings.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.