Извините, но я никогда не использовал NUnit.Mocks - но у меня есть некоторый опыт работы с NMock и Moq [что, кстати, я очень рекомендую]. Как правило, вы используете фиктивную библиотеку для генерации прокси для определений интерфейса, и я предполагаю, что NUnit.Mocks работает так же.
Поэтому, если вы хотите издеваться над своим синглтоном, вам, вероятно, придется сделать следующее:
а. Создайте интерфейс, скажем
// All methods you would like to mock from this class, should
// be members of this interface
public interface IWebSiteConfiguration
{
// Should match signature of method you are mocking
CodeType getCodeByCodeNameAndType (
string codeString,
CatalogType catalogType);
}
б. Интерфейс "Реализация"
// You've already written the method, interface matches signature,
// should be as easy as slapping interface on class declaration
public class WebSiteConfiguration : IWebSiteConfiguration { }
с. Интерфейс потребления
хорошо, так что шаг c. где большая часть вашей работы будет. По логике вещей, если вы издеваетесь над своим синглтоном, вы на самом деле проводите модульное тестирование потребителя [которое вы исключили из своего образца]. Для ц. просто добавьте параметр в ctor потребителя или добавьте общедоступное свойство типа 'IWebSiteConfiguration', а затем внутренне обратитесь к члену экземпляра и вызовите ваши методы для этого нового интерфейса. Учтите это,
был
public class MyClass
{
public MyClass () { }
public void DoSomething ()
{
// bad singleton! bad boy! static references are bad! you
// can't change them! convenient but bad!
code = WebSiteConfiguration.Instance.getCodeByCodeNameAndType (
"some.string",
someCatalog)
}
}
становится
public class MyClass
{
private readonly IWebSiteConfiguration _config = null;
// just so you don't break any other code, you can default
// to your static singleton on a default ctor
public MyClass () : this (WebSiteConfiguration.Instance) { }
// new constructor permits you to swap in any implementation
// including your mock!
public MyClass (IWebSiteConfiguration config)
{
_config = config;
}
public void DoSomething ()
{
// huzzah!
code = _config.getCodeByCodeNameAndType ("some.string", someCatalog)
}
}
В своем модульном тесте создайте макет, передайте ссылку на макет потребителю и протестируйте потребителя.
[Test]
public void Test ()
{
IWebSiteConfiguration mockConfig = null;
// setup mock instance and expectation via
// NUnit.Mocks, NMock, or Moq
MyClass myClass = new MyClass (mockConfig);
myClass.DoSomething ();
// verify results
}
Это также служит практическим введением в Dependency Injection [DI]. Это просто практика передачи или «внедрения» ссылок на службы [например, класс конфигурации вашего веб-сайта] потребителю, вместо того, чтобы потребитель вызывал службу напрямую [например, через статический одноэлементный класс].
Надеюсь, это поможет:)