public void GetOrCreate_CallsFaultyFactoryOnce()
        {
            // Arrange

            var key     = Guid.NewGuid().ToString();
            var options = new CacheEntryOptions(TimeSpan.FromMilliseconds(1));

            var factoryCallCount          = 0;
            Func <string, AClass> factory = _ =>
            {
                factoryCallCount++;
                throw new Exception();
            };

            var cache = Substitute.For <ICache>();

            cache.Get(key, typeof(AClass)).Returns((AClass)null);
            cache.When(c => c.GetOrCreate(key, typeof(AClass), options, Arg.Any <Func <string, AClass> >()))
            .Do(c => c.Arg <Func <string, AClass> >()(key));

            var logger    = Substitute.For <ILogger <ExceptionHandlingCacheDecorator> >();
            var decorator = new ExceptionHandlingCacheDecorator(cache, logger);


            // Act / Assert
            Assert.Throws <Exception>(() => decorator.GetOrCreate(key, typeof(AClass), options, factory));
            Assert.AreEqual(1, factoryCallCount);
        }
        public void GetOrCreateGeneric_ReturnsCachedValue()
        {
            // Arrange

            var key         = Guid.NewGuid().ToString();
            var cachedValue = new AClass();
            Func <string, AClass> factory = _ => new AClass();
            var options = new CacheEntryOptions(TimeSpan.FromMilliseconds(1));

            var cache = Substitute.For <ICache>();

            cache.GetIfCached(key, out Arg.Any <AClass>()).Returns(x =>
            {
                x[1] = cachedValue;
                return(true);
            });
            cache.GetOrCreate(key, options, Arg.Any <Func <string, AClass> >()).Returns(cachedValue);
            cache.Get(key, typeof(AClass)).Returns(cachedValue);

            var logger    = Substitute.For <ILogger <ExceptionHandlingCacheDecorator> >();
            var decorator = new ExceptionHandlingCacheDecorator(cache, logger);


            // Act
            var result = decorator.GetOrCreate(key, options, factory);

            // Assert
            Assert.AreEqual(cachedValue, result);
        }
        public void GetOrCreateGeneric_HandlesGetException()
        {
            // Arrange
            var key          = Guid.NewGuid().ToString();
            var factoryValue = new AClass();
            Func <string, AClass> factory = _ => factoryValue;
            var options = new CacheEntryOptions(TimeSpan.FromMilliseconds(1));
            var cache   = Substitute.For <ICache>();

            cache.Get <AClass>(key).Throws(new Exception());
            cache.GetOrCreate(key, options, Arg.Any <Func <string, AClass> >()).Throws(new Exception());
            var logger    = Substitute.For <ILogger <ExceptionHandlingCacheDecorator> >();
            var decorator = new ExceptionHandlingCacheDecorator(cache, logger);

            // Act
            var result = decorator.GetOrCreate(key, options, factory);

            // Assert
            Assert.AreEqual(factoryValue, result);
        }
        public void GetOrCreate_HandlesGetException()
        {
            // Arrange
            var key          = Guid.NewGuid().ToString();
            var factoryValue = new AClass();
            var cache        = Substitute.For <ICache>();

            cache.Get(key, typeof(AClass)).Throws(new Exception());
            var logger    = Substitute.For <ILogger <ExceptionHandlingCacheDecorator> >();
            var decorator = new ExceptionHandlingCacheDecorator(cache, logger);

            // Act
            var result = decorator.GetOrCreate(key,
                                               typeof(AClass),
                                               new CacheEntryOptions(new TimeSpan()),
                                               _ => factoryValue);

            // Assert
            Assert.AreEqual(factoryValue, result);
        }
        public void GetOrCreate_ReturnsCachedValue()
        {
            // Arrange
            var key         = Guid.NewGuid().ToString();
            var cachedValue = new AClass();
            var options     = new CacheEntryOptions(TimeSpan.FromMilliseconds(1));
            var cache       = Substitute.For <ICache>();

            cache.Get(key, typeof(AClass)).Returns(cachedValue);
            var logger    = Substitute.For <ILogger <ExceptionHandlingCacheDecorator> >();
            var decorator = new ExceptionHandlingCacheDecorator(cache, logger);

            // Act
            var result = decorator.GetOrCreate(key,
                                               typeof(AClass),
                                               options,
                                               _ => null);

            // Assert
            Assert.AreEqual(cachedValue, result);
        }
        public void GetOrCreateGeneric_CreatesValueType()
        {
            // Arrange
            var key                    = Guid.NewGuid().ToString();
            var factoryValue           = 1234;
            Func <string, int> factory = _ => factoryValue;
            var options                = new CacheEntryOptions(TimeSpan.FromMilliseconds(1));
            var cache                  = Substitute.For <IDistributedCache>();

            cache.Get(key).Returns((byte[])null);
            var logger    = Substitute.For <ILogger <ExceptionHandlingCacheDecorator> >();
            var decorator =
                new ExceptionHandlingCacheDecorator(new DistributedCache(cache, Substitute.For <ILogger <DistributedCache> >()),
                                                    logger);

            // Act
            var result = decorator.GetOrCreate(key, options, factory);

            // Assert
            Assert.AreEqual(factoryValue, result);
        }
        public void GetOrCreate_HandlesSetException()
        {
            // Arrange
            var key          = Guid.NewGuid().ToString();
            var factoryValue = new AClass();
            var options      = new CacheEntryOptions(TimeSpan.FromMilliseconds(1));
            var cache        = Substitute.For <ICache>();

            cache.When(c => c.Set(key, factoryValue, options)).Do(_ => throw new Exception());
            var logger    = Substitute.For <ILogger <ExceptionHandlingCacheDecorator> >();
            var decorator = new ExceptionHandlingCacheDecorator(cache, logger);

            // Act
            var result = decorator.GetOrCreate(key,
                                               typeof(AClass),
                                               options,
                                               _ => factoryValue);

            // Assert
            Assert.AreEqual(factoryValue, result);
        }