JUnit: @Before только для некоторых методов тестирования?

Я написал этот код некоторое время назад, не стесняйтесь использовать его.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace MediaBrowser.Library.Logging {
    public abstract class ThreadedLogger : LoggerBase {

        Queue<Action> queue = new Queue<Action>();
        AutoResetEvent hasNewItems = new AutoResetEvent(false);
        volatile bool waiting = false;

        public ThreadedLogger() : base() {
            Thread loggingThread = new Thread(new ThreadStart(ProcessQueue));
            loggingThread.IsBackground = true;
            loggingThread.Start();
        }


        void ProcessQueue() {
            while (true) {
                waiting = true;
                hasNewItems.WaitOne(10000,true);
                waiting = false;

                Queue<Action> queueCopy;
                lock (queue) {
                    queueCopy = new Queue<Action>(queue);
                    queue.Clear();
                }

                foreach (var log in queueCopy) {
                    log();
                }
            }
        }

        public override void LogMessage(LogRow row) {
            lock (queue) {
                queue.Enqueue(() => AsyncLogMessage(row));
            }
            hasNewItems.Set();
        }

        protected abstract void AsyncLogMessage(LogRow row);


        public override void Flush() {
            while (!waiting) {
                Thread.Sleep(1);
            }
        }
    }
}

Некоторые преимущества:

  • Он поддерживает работу фонового регистратора, поэтому ему не нужно раскручивать и раскручивать потоки.
  • Он использует один поток для обслуживания очереди, что означает, что никогда не будет ситуации, когда 100 потоков обслуживают очередь.
  • Копирует очереди, чтобы гарантировать, что очередь не заблокирована во время выполнения операции регистрации.
  • Он использует AutoResetEvent, чтобы гарантировать, что поток bg находится в состоянии ожидания
  • . ИМХО, им очень легко следовать

Вот немного улучшенная версия, имейте в виду, что я провел очень небольшое тестирование, но она решает некоторые незначительные проблемы.

public abstract class ThreadedLogger : IDisposable {

    Queue<Action> queue = new Queue<Action>();
    ManualResetEvent hasNewItems = new ManualResetEvent(false);
    ManualResetEvent terminate = new ManualResetEvent(false);
    ManualResetEvent waiting = new ManualResetEvent(false);

    Thread loggingThread; 

    public ThreadedLogger() {
        loggingThread = new Thread(new ThreadStart(ProcessQueue));
        loggingThread.IsBackground = true;
        // this is performed from a bg thread, to ensure the queue is serviced from a single thread
        loggingThread.Start();
    }


    void ProcessQueue() {
        while (true) {
            waiting.Set();
            int i = ManualResetEvent.WaitAny(new WaitHandle[] { hasNewItems, terminate });
            // terminate was signaled 
            if (i == 1) return; 
            hasNewItems.Reset();
            waiting.Reset();

            Queue<Action> queueCopy;
            lock (queue) {
                queueCopy = new Queue<Action>(queue);
                queue.Clear();
            }

            foreach (var log in queueCopy) {
                log();
            }    
        }
    }

    public void LogMessage(LogRow row) {
        lock (queue) {
            queue.Enqueue(() => AsyncLogMessage(row));
        }
        hasNewItems.Set();
    }

    protected abstract void AsyncLogMessage(LogRow row);


    public void Flush() {
        waiting.WaitOne();
    }


    public void Dispose() {
        terminate.Set();
        loggingThread.Join();
    }
}

Преимущества перед оригиналом:

  • Он одноразовый, поэтому вы можете избавиться от асинхронного регистратора
  • Улучшена семантика сброса
  • Он будет немного лучше реагировать на взрыв, сопровождаемый тишиной
40
задан Nick Heiner 10 October 2009 в 16:53
поделиться

2 ответа

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

36
ответ дан 27 November 2019 в 01:53
поделиться

Или используйте TestNG . Это дает вам более тонкий контроль над тестами.

4
ответ дан 27 November 2019 в 01:53
поделиться
Другие вопросы по тегам:

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