简体   繁体   中英

Disposing a singleton instance shared between NUnit tests

I have a bunch of NUnit acceptance tests (that is, not unit tests) that need to connect to several Redis instances during the course of the execution.

StackExchange.Redis best practices advise to store and reuse the ConnectionMultiplexer instances (see here: https://stackexchange.github.io/StackExchange.Redis/Basics ), so I came up with this singleton that allows to re-use a ConnectionMultiplexer object:

internal static class RedisConnectionCache
{
    // concurrency locks omitted for simplicity
    private static readonly Dictionary<string, IConnectionMultiplexer> ConnectionCache = new Dictionary<string, IConnectionMultiplexer>();
    public static IConnectionMultiplexer GetMultiplexer(string connectionString)
    {
        if (ConnectionCache.TryGetValue(connectionString, out var multiplexer))
        {
            return multiplexer;
        }

        var multiplexer= ConnectionMultiplexer.Connect(ConfigurationOptions.Parse(connectionString));
        ConnectionCache.Add(connectionString, multiplexer);

        return multiplexer;
    }
}

Which is then invoked like this in many tests:

var redisConnection = RedisConnectionCache.GetMultiplexer(connectionString);
var redisDb = redisConnection.GetDatabase(db);
redisDb.KeyDelete(key);

Unfortunately, since this is all happening inside many different NUnit test fixtures, I don't have a good way to dispose my dictionary of Redis connections.

Provided that I need to reuse the connection objects between different test fixtures inside the same test run, what are my options? So far, the best I can think of is OneTimeTearDown test that would empty the connections after all tests are done.

Setup Fixture does the trick here. One caveat is that I needed to put the class outside of the test namespaces to run after any tests in the assembly.

In a generic fashion, my code ended up being similar to this:

using NUnit.Framework;
// ReSharper disable CheckNamespace

[SetUpFixture]
public class SingletonTeardown
{
    [OneTimeTearDown]
    public void RunAfter()
    {
        if (SingletonType.Instance.IsValueCreated)
        {
            SingletonType.Instance.Value.Dispose();
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM