Removed ITvDbProvider

Added SetConstant to AutoMoq
This commit is contained in:
kay.one 2011-04-06 20:34:48 -07:00
parent c1bd62ae64
commit 0a783542a6
30 changed files with 343 additions and 16100 deletions

View File

@ -0,0 +1,125 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using AutoMoq.Unity;
using Microsoft.Practices.Unity;
using Moq;
using Moq.Language.Flow;
namespace AutoMoq
{
public class AutoMoqer
{
private IUnityContainer container;
private IDictionary<Type, object> registeredMocks;
public AutoMoqer()
{
SetupAutoMoqer(new UnityContainer());
}
internal AutoMoqer(IUnityContainer container)
{
SetupAutoMoqer(container);
}
public virtual T Resolve<T>()
{
return container.Resolve<T>();
}
public virtual Mock<T> GetMock<T>() where T : class
{
var type = GetTheMockType<T>();
if (GetMockHasNotBeenCalledForThisType(type))
CreateANewMockAndRegisterIt<T>(type);
return TheRegisteredMockForThisType<T>(type);
}
public virtual void SetConstant<T>(T instance) where T : class
{
container.RegisterInstance(instance);
SetMock(instance.GetType(), null);
}
internal virtual void SetMock(Type type, Mock mock)
{
if (registeredMocks.ContainsKey(type) == false)
registeredMocks.Add(type, mock);
}
#region private methods
private void SetupAutoMoqer(IUnityContainer container)
{
this.container = container;
registeredMocks = new Dictionary<Type, object>();
AddTheAutoMockingContainerExtensionToTheContainer(container);
container.RegisterInstance(this);
}
private static void AddTheAutoMockingContainerExtensionToTheContainer(IUnityContainer container)
{
container.AddNewExtension<AutoMockingContainerExtension>();
return;
}
private Mock<T> TheRegisteredMockForThisType<T>(Type type) where T : class
{
return (Mock<T>)registeredMocks.Where(x => x.Key == type).First().Value;
}
private void CreateANewMockAndRegisterIt<T>(Type type) where T : class
{
var mock = new Mock<T>();
container.RegisterInstance(mock.Object);
SetMock(type, mock);
}
private bool GetMockHasNotBeenCalledForThisType(Type type)
{
return registeredMocks.ContainsKey(type) == false;
}
private static Type GetTheMockType<T>() where T : class
{
return typeof(T);
}
#endregion
public ISetup<T> Setup<T>(Expression<Action<T>> expression) where T : class
{
return GetMock<T>().Setup(expression);
}
public ISetup<T, TResult> Setup<T, TResult>(Expression<Func<T, TResult>> expression) where T : class
{
return GetMock<T>().Setup(expression);
}
public void Verify<T>(Expression<Action<T>> expression) where T : class
{
GetMock<T>().Verify(expression);
}
public void Verify<T>(Expression<Action<T>> expression, string failMessage) where T : class
{
GetMock<T>().Verify(expression, failMessage);
}
public void Verify<T>(Expression<Action<T>> expression, Times times) where T : class
{
GetMock<T>().Verify(expression, times);
}
public void Verify<T>(Expression<Action<T>> expression, Times times, string failMessage) where T : class
{
GetMock<T>().Verify(expression, times, failMessage);
}
}
}

View File

@ -0,0 +1,22 @@
 Copyright (c) 2010 Darren Cauthon
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,80 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.Practices.ObjectBuilder2;
using Microsoft.Practices.Unity;
using Moq;
namespace AutoMoq.Unity
{
internal class AutoMockingBuilderStrategy : BuilderStrategy
{
private readonly MockFactory mockFactory;
private readonly IEnumerable<Type> registeredTypes;
private readonly IUnityContainer container;
public AutoMockingBuilderStrategy(IEnumerable<Type> registeredTypes, IUnityContainer container)
{
mockFactory = new MockFactory(MockBehavior.Loose);
this.registeredTypes = registeredTypes;
this.container = container;
}
public override void PreBuildUp(IBuilderContext context)
{
var autoMoqer = container.Resolve<AutoMoqer>();
var type = GetTheTypeFromTheBuilderContext(context);
if (AMockObjectShouldBeCreatedForThisType(type))
{
var mock = CreateAMockObject(type);
context.Existing = mock.Object;
autoMoqer.SetMock(type, mock);
}
}
#region private methods
private bool AMockObjectShouldBeCreatedForThisType(Type type)
{
return TypeIsNotRegistered(type) && type.IsInterface;
}
private static Type GetTheTypeFromTheBuilderContext(IBuilderContext context)
{
return ((NamedTypeBuildKey) context.OriginalBuildKey).Type;
}
private bool TypeIsNotRegistered(Type type)
{
return registeredTypes.Any(x => x.Equals(type)) == false;
}
private Mock CreateAMockObject(Type type)
{
var createMethod = GenerateAnInterfaceMockCreationMethod(type);
return InvokeTheMockCreationMethod(createMethod);
}
private Mock InvokeTheMockCreationMethod(MethodInfo createMethod)
{
return (Mock) createMethod.Invoke(mockFactory, new object[] {new List<object>().ToArray()});
}
private MethodInfo GenerateAnInterfaceMockCreationMethod(Type type)
{
var createMethodWithNoParameters = mockFactory.GetType().GetMethod("Create", EmptyArgumentList());
return createMethodWithNoParameters.MakeGenericMethod(new[] {type});
}
private static Type[] EmptyArgumentList()
{
return new[] {typeof (object[])};
}
#endregion
}
}

View File

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.ObjectBuilder;
namespace AutoMoq.Unity
{
internal class AutoMockingContainerExtension : UnityContainerExtension
{
private readonly IList<Type> registeredTypes = new List<Type>();
protected override void Initialize()
{
SetEventsOnContainerToTrackAllRegisteredTypes();
SetBuildingStrategyForBuildingUnregisteredTypes();
}
#region private methods
private void SetEventsOnContainerToTrackAllRegisteredTypes()
{
Context.Registering += ((sender, e) => RegisterType(e.TypeFrom));
Context.RegisteringInstance += ((sender, e) => RegisterType(e.RegisteredType));
}
private void RegisterType(Type typeToRegister)
{
registeredTypes.Add(typeToRegister);
}
private void SetBuildingStrategyForBuildingUnregisteredTypes()
{
var strategy = new AutoMockingBuilderStrategy(registeredTypes, Container);
Context.Strategies.Add(strategy, UnityBuildStage.PreCreation);
}
#endregion
}
}

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using AutoMoq;
using Gallio.Framework;
using MbUnit.Framework;
using MbUnit.Framework.ContractVerifiers;
@ -23,17 +24,20 @@ namespace NzbDrone.Core.Test
const string value = "MY_VALUE";
//Arrange
var repo = new Mock<IRepository>();
var config = new Config { Key = key, Value = value };
repo.Setup(r => r.Single<Config>(key)).Returns(config);
var target = new ConfigProvider(repo.Object);
var mocker = new AutoMoqer();
mocker.GetMock<IRepository>()
.Setup(r => r.Single<Config>(key))
.Returns(config);
//Act
target.SetValue(key, value);
mocker.Resolve<ConfigProvider>().SetValue(key, value);
//Assert
repo.Verify(c => c.Update(config));
repo.Verify(c => c.Add(It.IsAny<Config>()), Times.Never());
mocker.GetMock<IRepository>().Verify(c => c.Update(config));
mocker.GetMock<IRepository>().Verify(c => c.Add(It.IsAny<Config>()), Times.Never());
}
[Test]
@ -43,17 +47,20 @@ namespace NzbDrone.Core.Test
const string value = "MY_VALUE";
//Arrange
var repo = new Mock<IRepository>();
repo.Setup(r => r.Single<Config>(It.IsAny<string>())).Returns<Config>(null).Verifiable();
var target = new ConfigProvider(repo.Object);
var mocker = new AutoMoqer();
mocker.GetMock<IRepository>()
.Setup(r => r.Single<Config>(It.IsAny<string>()))
.Returns<Config>(null)
.Verifiable();
//Act
target.SetValue(key, value);
mocker.Resolve<ConfigProvider>().SetValue(key, value);
//Assert
repo.Verify();
repo.Verify(r => r.Update(It.IsAny<Config>()), Times.Never());
repo.Verify(r => r.Add(It.Is<Config>(c => c.Key == key && c.Value == value)), Times.Once());
mocker.GetMock<IRepository>().Verify();
mocker.GetMock<IRepository>().Verify(r => r.Update(It.IsAny<Config>()), Times.Never());
mocker.GetMock<IRepository>().Verify(r => r.Add(It.Is<Config>(c => c.Key == key && c.Value == value)), Times.Once());
}
}
}

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using AutoMoq;
using FizzWare.NBuilder;
using Gallio.Framework;
using MbUnit.Framework;
@ -27,8 +28,9 @@ namespace NzbDrone.Core.Test
public void RefreshEpisodeInfo()
{
//Arrange
int seriesId = 71663;
int episodeCount = 10;
const int seriesId = 71663;
const int episodeCount = 10;
var fakeEpisodes = Builder<TvdbSeries>.CreateNew().With(
c => c.Episodes =
new List<TvdbEpisode>(Builder<TvdbEpisode>.CreateListOfSize(episodeCount).
@ -37,23 +39,26 @@ namespace NzbDrone.Core.Test
.Build())
).With(c => c.Id = seriesId).Build();
var tvdbMock = new Mock<ITvDbProvider>();
tvdbMock.Setup(c => c.GetSeries(seriesId, true)).Returns(fakeEpisodes).Verifiable();
var mocker = new AutoMoqer();
mocker.SetConstant(MockLib.GetEmptyRepository());
mocker.GetMock<TvDbProvider>()
.Setup(c => c.GetSeries(seriesId, true))
.Returns(fakeEpisodes).Verifiable();
//mocker.GetMock<IRepository>().SetReturnsDefault();
var kernel = new MockingKernel();
kernel.Bind<IRepository>().ToConstant(MockLib.GetEmptyRepository(false)).InSingletonScope();
kernel.Bind<ITvDbProvider>().ToConstant(tvdbMock.Object);
kernel.Bind<IEpisodeProvider>().To<EpisodeProvider>().InSingletonScope();
//Act
var sw = Stopwatch.StartNew();
kernel.Get<IEpisodeProvider>().RefreshEpisodeInfo(seriesId);
mocker.Resolve<EpisodeProvider>().RefreshEpisodeInfo(seriesId);
var actualCount = mocker.Resolve<EpisodeProvider>().GetEpisodeBySeries(seriesId);
//Assert
tvdbMock.VerifyAll();
Assert.Count(episodeCount, kernel.Get<IEpisodeProvider>().GetEpisodeBySeries(seriesId));
Console.WriteLine("Duration: " + sw.Elapsed.ToString());
mocker.GetMock<TvDbProvider>().VerifyAll();
Assert.Count(episodeCount, actualCount);
Console.WriteLine("Duration: " + sw.Elapsed);
}
[Test]

View File

@ -35,9 +35,6 @@
<Reference Include="Accessibility">
<EmbedInteropTypes>True</EmbedInteropTypes>
</Reference>
<Reference Include="AutoMoq">
<HintPath>..\packages\AutoMoq.1.3.1.3\lib\AutoMoq.dll</HintPath>
</Reference>
<Reference Include="Castle.Core, Version=2.5.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\NzbDrone.Core\Libraries\Castle.Core.dll</HintPath>
@ -88,6 +85,9 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="AutoMoq\AutoMoq.cs" />
<Compile Include="AutoMoq\Unity\AutoMockingBuilderStrategy.cs" />
<Compile Include="AutoMoq\Unity\AutoMockingContainerExtension.cs" />
<Compile Include="RssProviderTest.cs" />
<Compile Include="HistoryProviderTest.cs" />
<Compile Include="MediaFileProviderTests.cs" />
@ -114,6 +114,7 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="AutoMoq\License.txt" />
<Content Include="Files\Feed.nzbmatrix.com.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>

View File

@ -3,6 +3,7 @@ using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using AutoMoq;
using FizzWare.NBuilder;
using Gallio.Framework;
using MbUnit.Framework;
@ -28,30 +29,36 @@ namespace NzbDrone.Core.Test
public void Map_path_to_series()
{
//Arrange
TvdbSeries fakeSeries = Builder<TvdbSeries>.CreateNew().With(f => f.SeriesName = "The Simpsons").Build();
var fakeSearch = Builder<TvdbSearchResult>.CreateNew().Build();
fakeSearch.Id = fakeSeries.Id;
fakeSearch.SeriesName = fakeSeries.SeriesName;
var fakeSeries = Builder<TvdbSeries>.CreateNew()
.With(f => f.SeriesName = "The Simpsons")
.Build();
var moqData = new Mock<IRepository>();
var moqTvdb = new Mock<ITvDbProvider>();
var fakeSearch = Builder<TvdbSearchResult>.CreateNew()
.With(s => s.Id = fakeSeries.Id)
.With(s => s.SeriesName = fakeSeries.SeriesName)
.Build();
moqData.Setup(f => f.Exists<Series>(c => c.SeriesId == It.IsAny<int>())).Returns(false);
moqTvdb.Setup(f => f.GetSeries(It.IsAny<String>())).Returns(fakeSearch);
moqTvdb.Setup(f => f.GetSeries(fakeSeries.Id, false)).Returns(fakeSeries).Verifiable();
var mocker = new AutoMoqer();
var kernel = new MockingKernel();
kernel.Bind<IRepository>().ToConstant(moqData.Object);
kernel.Bind<ITvDbProvider>().ToConstant(moqTvdb.Object);
kernel.Bind<ISeriesProvider>().To<SeriesProvider>();
mocker.GetMock<IRepository>()
.Setup(f => f.Exists<Series>(c => c.SeriesId == It.IsAny<int>()))
.Returns(false);
mocker.GetMock<TvDbProvider>()
.Setup(f => f.GetSeries(It.IsAny<String>()))
.Returns(fakeSearch);
mocker.GetMock<TvDbProvider>()
.Setup(f => f.GetSeries(fakeSeries.Id, false))
.Returns(fakeSeries)
.Verifiable();
//Act
var seriesController = kernel.Get<ISeriesProvider>();
var mappedSeries = seriesController.MapPathToSeries(@"D:\TV Shows\The Simpsons");
var mappedSeries = mocker.Resolve<SeriesProvider>().MapPathToSeries(@"D:\TV Shows\The Simpsons");
//Assert
moqTvdb.VerifyAll();
mocker.GetMock<TvDbProvider>().VerifyAll();
Assert.AreEqual(fakeSeries, mappedSeries);
}

View File

@ -4,5 +4,4 @@
<package id="NBuilder" version="2.3.0.0" />
<package id="Moq" version="4.0.10827" />
<package id="Unity" version="2.0" />
<package id="AutoMoq" version="1.3.1.3" />
</packages>

View File

@ -63,7 +63,7 @@ namespace NzbDrone.Core
_kernel.Bind<IEpisodeProvider>().To<EpisodeProvider>();
_kernel.Bind<IUpcomingEpisodesProvider>().To<UpcomingEpisodesProvider>();
_kernel.Bind<IDiskProvider>().To<DiskProvider>();
_kernel.Bind<ITvDbProvider>().To<TvDbProvider>();
_kernel.Bind<TvDbProvider>().To<TvDbProvider>();
_kernel.Bind<IDownloadProvider>().To<SabProvider>();
_kernel.Bind<HttpProvider>().To<HttpProvider>();
_kernel.Bind<IHistoryProvider>().To<HistoryProvider>();

View File

@ -223,7 +223,6 @@
<Compile Include="Providers\IEpisodeProvider.cs" />
<Compile Include="Providers\ISeasonProvider.cs" />
<Compile Include="Providers\ISeriesProvider.cs" />
<Compile Include="Providers\ITvDbProvider.cs" />
<Compile Include="Providers\SabProvider.cs" />
<Compile Include="Providers\SeasonProvider.cs" />
<Compile Include="Repository\Episode.cs" />

View File

@ -16,13 +16,13 @@ namespace NzbDrone.Core.Providers
private readonly IRepository _sonicRepo;
private readonly ISeriesProvider _series;
private readonly ISeasonProvider _seasons;
private readonly ITvDbProvider _tvDb;
private readonly TvDbProvider _tvDb;
private readonly IHistoryProvider _history;
private readonly IQualityProvider _quality;
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public EpisodeProvider(IRepository sonicRepo, ISeriesProvider seriesProvider,
ISeasonProvider seasonProvider, ITvDbProvider tvDbProvider,
ISeasonProvider seasonProvider, TvDbProvider tvDbProvider,
IHistoryProvider history, IQualityProvider quality)
{
_sonicRepo = sonicRepo;

View File

@ -1,13 +0,0 @@
using System.Collections.Generic;
using TvdbLib.Data;
namespace NzbDrone.Core.Providers
{
public interface ITvDbProvider
{
IList<TvdbSearchResult> SearchSeries(string name);
int GetBestMatch(List<TvdbSearchResult> searchResults, string searchString);
TvdbSearchResult GetSeries(string title);
TvdbSeries GetSeries(int id, bool loadEpisodes);
}
}

View File

@ -21,12 +21,12 @@ namespace NzbDrone.Core.Providers
private readonly IConfigProvider _config;
private readonly IRepository _sonioRepo;
private readonly ITvDbProvider _tvDb;
private readonly TvDbProvider _tvDb;
private readonly IQualityProvider _quality;
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public SeriesProvider(IConfigProvider configProvider,
IRepository dataRepository, ITvDbProvider tvDbProvider, IQualityProvider quality)
IRepository dataRepository, TvDbProvider tvDbProvider, IQualityProvider quality)
{
_config = configProvider;
_sonioRepo = dataRepository;

View File

@ -9,7 +9,7 @@ using TvdbLib.Data;
namespace NzbDrone.Core.Providers
{
public class TvDbProvider : ITvDbProvider
public class TvDbProvider
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private static readonly Regex CleanUpRegex = new Regex(@"((\s|^)the(\s|$))|((\s|^)and(\s|$))|[^a-z]", RegexOptions.IgnoreCase | RegexOptions.Compiled);
@ -22,9 +22,9 @@ namespace NzbDrone.Core.Providers
_handler = new TvdbHandler(new XmlCacheProvider(CentralDispatch.AppPath + @"\cache\tvdb"), TVDB_APIKEY);
}
#region ITvDbProvider Members
#region TvDbProvider Members
public IList<TvdbSearchResult> SearchSeries(string title)
public virtual IList<TvdbSearchResult> SearchSeries(string title)
{
Logger.Debug("Searching TVDB for '{0}'", title);
var result = _handler.SearchSeries(title);
@ -34,7 +34,7 @@ namespace NzbDrone.Core.Providers
}
public TvdbSearchResult GetSeries(string title)
public virtual TvdbSearchResult GetSeries(string title)
{
var searchResults = SearchSeries(title);
if (searchResults.Count == 0)
@ -52,7 +52,7 @@ namespace NzbDrone.Core.Providers
return null;
}
public int GetBestMatch(List<TvdbSearchResult> searchResults, string title)
public virtual int GetBestMatch(List<TvdbSearchResult> searchResults, string title)
{
if (searchResults.Count == 0)
return 0;
@ -69,7 +69,7 @@ namespace NzbDrone.Core.Providers
return searchResults[0].Id;
}
public TvdbSeries GetSeries(int id, bool loadEpisodes)
public virtual TvdbSeries GetSeries(int id, bool loadEpisodes)
{
Logger.Debug("Fetching SeriesId'{0}' from tvdb", id);
return _handler.GetSeries(id, TvdbLanguage.DefaultLanguage, loadEpisodes, false, false);

Binary file not shown.

Binary file not shown.

View File

@ -1,39 +0,0 @@
Copyright (c) 2007. Clarius Consulting, Manas Technology Solutions, InSTEDD
http://code.google.com/p/moq/
All rights reserved.
Redistribution and use in source and binary forms,
with or without modification, are permitted provided
that the following conditions are met:
* Redistributions of source code must retain the
above copyright notice, this list of conditions and
the following disclaimer.
* Redistributions in binary form must reproduce
the above copyright notice, this list of conditions
and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of Clarius Consulting, Manas Technology Solutions or InSTEDD nor the
names of its contributors may be used to endorse
or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
[This is the BSD license, see
http://www.opensource.org/licenses/bsd-license.php]

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff