Tworząc testy jednostkowe ważne jest, aby testy działały bardzo szybko, oraz niezależnie od zewnętrznych zasobów, takich jak np. web service, dostęp do plików itp. Mówi o tym, m.in. Roy Osherove podczas swoich szkoleń, np. Understanding Test Driven Development
Jednym z takich zewnętrznych zasobów dla aplikacji internetowych, jest plik konfiguracyjny web.config. Przykładowy sposób, jak skutecznie zastosować DI oraz testy jednostkowe dla tego rozwiązania pokazuje na swoim blogu KAZI MANZUR RASHID. Niestety dla mnie, Kazi pokazuje to z wykorzystaniem "Mock", natomiast Ja, pod wpływem postów Macieja Aniserowicza jako narzędzie 'mockujące' postanowiłem wykorzystywać FakeItEasy. Poniżej prezentuję działające rozwiązanie wykorzystujące bibliotekę FakeItEasy.
Ponieważ zmieniam tylko bibliotekę 'Mock' na "FakeItEasy' to podstawowe klasy, pozostały takie same, jak w kodzie Kazi Manur'a
public interface IConfigurationManagerAby pokazać bardziej realistyczny przykład użycia, utworzyłem klasę BL (Business Logic), która do swojej pracy wykorzystuje dane, pobrane z web.config. Założyłem również, że plik web.config posiada wpis o nazwie customAppSetting z wartością "test".
{
NameValueCollection AppSettings
{
get;
}
string ConnectionStrings(string name);
T GetSection<T>(string sectionName);
}
public class ConfigurationManagerWrapper : IConfigurationManager
{
public NameValueCollection AppSettings
{
get
{
return ConfigurationManager.AppSettings;
}
}
public string ConnectionStrings(string name)
{
return ConfigurationManager.ConnectionStrings[name].ConnectionString;
}
public T GetSection<T>(string sectionName)
{
return (T)ConfigurationManager.GetSection(sectionName);
}
}
using System;Praktyczne wykorzystanie klasy BL przez solucję produkcyjną:
using System.Collections.Generic;
using System.Linq;
using System.Web;
public class BL
{
private readonly IConfigurationManager configuration;
public BL()
{
this.configuration = new ConfigurationManagerWrapper();
}
public BL(IConfigurationManager configuration)
{
this.configuration = configuration;
}
public string GetAppSetting(string customAppSettingName)
{
string customAppSetting = configuration.AppSettings[customAppSettingName];
//TODO: some business logic
return customAppSetting;
}
}
private void ProductionWebConfig()Praktyczne wykorzystanie klasy BL przez bibliotekę testującą:
{
BL businessLogic = new BL(new ConfigurationManagerWrapper());
string customAppSetting = businessLogic.GetAppSetting("customAppSetting");
}
[Fact]
public void GetAppSetting_PositiveString_StringTest()
{
var customAppSetting = new NameValueCollection { { "customAppSetting", "test" } };
IConfigurationManager fakeConfiguration = A.Fake<IConfigurationManager>();
A.CallTo(() => fakeConfiguration.AppSettings).Returns(customAppSetting);
BL bl = new BL(fakeConfiguration);
string fakeString = bl.GetAppSetting("customAppSetting");
string realString = "test";
Assert.Equal(fakeString, realString);
}
Brak komentarzy:
Prześlij komentarz