Задержанное выполнение в C#

Так как каждый тест выполняется независимо с новым экземпляром объекта, нет большого количества точки к Тестовому объекту, имеющему внутреннее состояние за исключением того, что общее между setUp() и отдельный тест и tearDown(). Это - одна причина (в дополнение к причинам, которые другие привели), что хорошо использовать setUp() метод.

Примечание: это - плохая идея для тестового объекта JUnit поддержать статическое состояние! При использовании статической переменной в тестах для чего-нибудь кроме отслеживания или диагностических целей Вы делаете недействительным часть цели JUnit, который является, что тесты могут (май) выполняются в любом порядке, каждый тест, работающий с новым, чистым состоянием.

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

В Вашем случае, где Вы просто создаете пустой список, я сделал бы тот же способ, которым Вы предлагаете: Присвойте новый список при объявлении. Особенно, потому что этот способ, которым у Вас есть опция маркировки его final, если это имеет смысл для Вашего тестового класса.

12
задан Larsenal 10 September 2009 в 01:08
поделиться

6 ответов

Вы можете использовать лямбды / делегаты:

Func<string> doit = () => DoFoo();
//  - or -
Func<string> doit = DoFoo;

Позже вы можете вызвать doit точно так же, как метод:

string x = doit();

Я думаю, что ближе всего вы можете получить что-то вроде этого :

Lazy<string> x = DoFoo;

string y = x; // "use" x

С определением Lazy , похожим на это (непроверено):

public class Lazy<T>
{
    private readonly Func<T> func;
    private bool hasValue;
    private T value;

    public Lazy(Func<T> func)
    {
        this.func = func;
        this.hasValue = false;
    }

    public static implicit operator Lazy<T>(Func<T> func)
    {
        return new Lazy<T>(func);
    }

    public static implicit operator T(Lazy<T> lazy)
    {
        if (!lazy.hasValue)
        {
            lazy.value = lazy.func();
            lazy.hasValue = true;
        }
        return lazy.value;
    }
}

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

// none of these will compile...
Lazy<string> x = DoFoo;
Lazy<string> y = () => DoFoo();
Lazy<string> z = delegate() { return DoFoo(); };

// these all work...
Lazy<string> a = (Func<string>)DoFoo;
Lazy<string> b = (Func<string>)(() => DoFoo());
Lazy<string> c = new Func<string>(DoFoo);
Lazy<string> d = new Func<string>(() => DoFoo());
Lazy<string> e = new Lazy<string>(DoFoo);
Lazy<string> f = new Lazy<string>(() => DoFoo);
18
ответ дан 2 December 2019 в 05:28
поделиться

Несмотря на то, что это несколько грязно, вы всегда можете использовать ключевое слово yield:

public IEnumerable<int> DoFoo() {
   Console.WriteLine("doing foo");
   yield return 10;
}

[Test]
public void TestMethod()
{
    var x = DoFoo();
    Console.WriteLine("foo aquired?");
    Console.WriteLine(x.First());
}
3
ответ дан 2 December 2019 в 05:28
поделиться

Один из вариантов - использовать класс Lazy , ранее из библиотеки параллельных расширений, теперь являющийся частью .Net Framework 4.0.

Он позволяет задерживать обработку данных с учетом потоков.

6
ответ дан 2 December 2019 в 05:28
поделиться

Вместо передачи строки x передайте делегату, который предоставляет вам string

Func<String> fooFunc=()=>DoFoo();
1
ответ дан 2 December 2019 в 05:28
поделиться

Почему бы просто не вызвать DoFoo (), пока вы этого не сделаете?

- Edit

Я имею в виду, что вы имеете в виду «использовать»

Например, если вы хотите, чтобы он вызывался при вызове '.ToString ()', вы всегда можете унаследовать класс и реализовать там свою функцию (но это было бы совершенно не интуитивно, IMHO).

0
ответ дан 2 December 2019 в 05:28
поделиться

Вы в значительной степени описываете LINQ В бою. Запрос linq описывает, как получить данные, но данные извлекаются (вызывается DoFunc) только при повторении запроса. Подумайте, можете ли вы изменить свой дизайн, чтобы он принимал IQueryable , где вам нужна строка .

0
ответ дан 2 December 2019 в 05:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: