Skip to content

Commit

Permalink
Merge pull request #123 from scott-xu/master
Browse files Browse the repository at this point in the history
Should only add public interfaces
  • Loading branch information
kzu committed Aug 6, 2014
2 parents 694df01 + ceca9b6 commit 4ade20b
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 3 deletions.
5 changes: 3 additions & 2 deletions Source/InterceptorStrategies.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ internal class InvokeBase : IInterceptStrategy
{
public InterceptionAction HandleIntercept(ICallContext invocation, InterceptorContext ctx, CurrentInterceptContext localctx)
{
if (invocation.Method.DeclaringType == typeof(object) ||
invocation.Method.DeclaringType.IsClass && !invocation.Method.IsAbstract && ctx.Mock.CallBase
if (invocation.Method.DeclaringType == typeof(object) || // interface proxy
ctx.Mock.ImplementedInterfaces.Contains(invocation.Method.DeclaringType) && !invocation.Method.IsEventAttach() && !invocation.Method.IsEventDetach() && ctx.Mock.CallBase || // class proxy with explicitly implemented interfaces. The method's declaring type is the interface and the method couldn't be abstract
invocation.Method.DeclaringType.IsClass && !invocation.Method.IsAbstract && ctx.Mock.CallBase // class proxy
)
{
// Invoke underlying implementation.
Expand Down
3 changes: 2 additions & 1 deletion Source/Mock.Generic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@

using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Linq.Expressions;
using Moq.Language.Flow;
using Moq.Proxy;
Expand Down Expand Up @@ -111,7 +112,7 @@ public Mock(MockBehavior behavior, params object[] args)
this.Behavior = behavior;
this.Interceptor = new Interceptor(behavior, typeof(T), this);
this.constructorArguments = args;
this.ImplementedInterfaces.AddRange(typeof(T).GetInterfaces());
this.ImplementedInterfaces.AddRange(typeof(T).GetInterfaces().Where(i => (i.IsPublic || i.IsNestedPublic) && !i.IsImport));
this.ImplementedInterfaces.Add(typeof(IMocked<T>));

this.CheckParameters();
Expand Down
48 changes: 48 additions & 0 deletions UnitTests/AsInterfaceFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,23 @@ public void VerifiesExpectationOnAddedInterfaceCastedDynamically()
bag.As<IFoo>().Verify(f => f.Execute());
}

[Fact]
public void ShouldBeAbleToCastToImplementedInterface()
{
var fooBar = new Mock<FooBar>();
var obj = fooBar.Object;
Assert.DoesNotThrow(() => fooBar.As<IFoo>());
}

[Fact]
public void ShouldNotThrowIfCallExplicitlyImplementedInterfacesMethodWhenCallBaseIsTrue()
{
var fooBar = new Mock<FooBar>();
fooBar.CallBase = true;
var bag = (IBag)fooBar.Object;
Assert.DoesNotThrow(() => bag.Get("test"));
}

public interface IFoo
{
void Execute();
Expand All @@ -168,5 +185,36 @@ public interface IBag
void Add(string key, object o);
object Get(string key);
}

internal interface IBar
{
void Test();
}

public abstract class FooBar : IFoo, IBag, IBar
{
public abstract void Execute();

public abstract string Execute(string command);

public abstract string Execute(string arg1, string arg2);

public abstract string Execute(string arg1, string arg2, string arg3);

public abstract string Execute(string arg1, string arg2, string arg3, string arg4);

public abstract int Value { get; set; }

void IBag.Add(string key, object o)
{
}

object IBag.Get(string key)
{
return null;
}

public abstract void Test();
}
}
}

0 comments on commit 4ade20b

Please sign in to comment.