2013-05-31 3 views
1

У меня есть одноэлементный объект в C#.Как запустить тестовые примеры для объекта Singleton с несколькими состояниями?

Этот объект singleton работает на основе определенного для него состояния.

У меня нет способа переключить состояние одноэлементного объекта во время выполнения. Также мне это не нужно, поскольку приложение всегда запускается в одном состоянии и остается в том же состоянии.

Проблема заключается в написании тестовых примеров. Я написал тестовые примеры для каждого штата. Но я не могу запустить его, потому что для всех тестовых случаев у меня есть один объект с одним состоянием.

Как запустить тесты для другого состояния. Как воссоздать объект для каждого теста?

Я не хочу менять одноэлементный объектный код для тестовых случаев.

Любые мысли или идеи будут высоко оценены.

ответ

4

Это одна из причин, по которой вам не нужно самостоятельно управлять временем жизни класса, но иметь контейнер инверсии управления (IoC), такой как Autofac или , сделайте это за вас. Затем вы просто создаете класс, который похож на любой другой класс, и скажите вашему контейнеру IoC создать его как одноэлементный.

См. Также An Autofac Lifetime Primer.

В случае, если вы не можете использовать контейнер IoC (не можете думать ни о чем, но давайте будем гибкими), вы можете создать класс internal, содержащий логику «singleton», и этот внутренний класс только что внутренний класс, не одноэлементно ...

internal class MyLogic 
{ 
    ... 
} 

а потом завернуть его в общественном классе, и сделать это одноплодной. Если вы поместите оба этих класса вместе в один проект, то внутренний класс (реализация вашей бизнес-логики) недоступен для вашего приложения, доступна только общедоступная версия синглтона.

public sealed class MySingleton 
{ 
    private MySingleton() { Implementation = new MyLogic(); } 

    public static MySingleton Instance { ... } 

    private MyLogic Implementation { get; set; } 

    ... 
} 

Но тогда вы можете указать в вашем AssemblyInfo, что ваш блок-тест проект имеет доступ к внутреннему классу с помощью

[assembly: InternalsVisibleTo("MySolution.UnitTests")] 

Таким образом, вы можете модульное тестирование вашей логики класса в то время как ваши приложение (ы) может использовать его только как Singleton.

Откровенно говоря, я предпочитаю путь IoC, но если это ново для вас, скорее всего, быстрее реализовать вышеуказанное решение.

Удачи вам!

+0

hmmm .. OK. но все же есть ли решение без использования IoC? –

+0

это одно из решений. благодаря –

0

Я хотел бы предложить вам избежать одиночек, когда это возможно, увидеть этот разговор по Misko Hevery: The Clean Code Talks

1

Я не хочу, чтобы изменить одноплодный объектный код для тестов.

Возможно, пришло время подумать об изменении его для всей вашей программы. Есть ли причина, по которой вы нуждаетесь Это должно быть одноточечным?Синглтон - отличный образец , если вам это нужно, но его часто используют люди, которые хотят использовать глобальные переменные, но слышали, что они злые. Теперь они программируют синглтоны, потому что они работают одинаково, будучи одним из тех «шаблонов», которые являются классными ООП.

Но одноэлемент - не что иное, как глобальное. И он имеет те же проблемы, что и глобальный. Если вы используете этот шаблон, убедитесь, что вы на самом деле нуждаетесь в, потому что он поставляется с проблемами, и вам нужно весовать преимущества против недостатков. Если вы не используете преимущества, у вас есть только недостатки.

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