Mocking internal (Friend) types

316 views
Skip to first unread message

sonof...@comcast.net

unread,
Sep 23, 2009, 11:31:39 AM9/23/09
to Moq Discussions
I have run into a serious issue implementing Moq for our testing needs
- and it very well may be a show-stopper for us. This is
disappointing because Moq appears to be a perfect fit for our needs
otherwise.

The problem is simply that we cannot mock internal (Friend in Visual
Basic) types.

We scope defensively and, as a result, the vast majority of our types
or scoped internal to prevent unwanted access to our intellectual
property. We only scope types public if they are intentionally part
of our public API. We also use obfuscation on our released code to
further protect our IP. We also place all of our tests in satellite
assemblies and grant them access to our internal types using the
InternalsVisibleTo attribute.

All of this is such common practice (has been the case with the last 6
clients I've worked with as a consultant/contractor as well as my
current company), that I am amazed such a limitation was placed in
Moq. After all, the whole point of the internal (Friend) scope is for
these types to "appear" public by other types within the same assembly
or a satellite assembly when granted access via the InternalsVisibleTo
attribute.

Does anyone have any idea if we should be expecting to see this change
in the (very) near future so that we can continue using Moq? Any
suggestions how to work around this without sacrificing our IP?

Andrew Kazyrevich

unread,
Sep 23, 2009, 12:16:38 PM9/23/09
to moq...@googlegroups.com
InternalsVisibleTo attribute (applied to the assembly with the types - not to the tests assembly) should help.

Kenneth Xu

unread,
Sep 23, 2009, 1:03:50 PM9/23/09
to moq...@googlegroups.com
In order to let Moq to mock your internals, you need to let your
assembly internal visible to the dynamic assembly created by Moq:

http://blog.ashmind.com/index.php/2008/05/09/mocking-internal-interfaces-with-moq/

I assume you strong sign your test assembly as well, otherwise, I can
easily create an assembly with the same name as your test assembly and
see all your internals, which defeats your purpose of IP protection.
Now if you do make internal visible to the generated assembly as I
suggested, again I can easily create same named assembly and call your
internals.

So I see more of an IP protection strategy problem rather then the
limitation of Moq I think.

IMHO, "internal" is not the answer to IP protection. Raflector will
should me all your internals anyway.

andreister

unread,
Sep 23, 2009, 3:14:20 PM9/23/09
to Moq Discussions
Doh, apparently I hadn't read your message properly - you're already
using InternalsVisibleTo..

Not sure why it doesn't work then. Do you get any exceptions? Can you
post a small repro?


On Sep 23, 5:31 pm, "james.mil...@accellos.com"

sonof...@comcast.net

unread,
Sep 23, 2009, 10:37:14 PM9/23/09
to Moq Discussions
I was able to get past the original problem adding the
InternalsVisibleTo attribute for the DynamicProxyGenAssembly2 assembly
as indicated in the blog post but I'm still not able to create the
mock. Now I am getting the following exception:

Test method Application1.Testing.MyCommandTests.Test1 threw
exception: System.TypeLoadException:
Type
'Castle.Proxies.ICommandProxy7d60919c623b4682b7ca123662aa4c77' from
assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral,
PublicKeyToken=null' is attempting to implement an inaccessible
interface..

Of course, my interface is scoped internal. Aside from getting the
mock to work, I can make use of it without a problem from the
indicated testing assembly.

Any ideas?


As for the IP question, you are correct that scoping our types
internal is not enough all by itself to secure our IP. But running
obfuscation takes care of the Reflector problem because the internal
types in the assembly are no longer readible - or even visible in some
cases.

Olof Bjarnason

unread,
Sep 24, 2009, 2:11:23 AM9/24/09
to moq...@googlegroups.com
2009/9/24 james....@accellos.com <sonof...@comcast.net>:
IP-problematics aside (I'm not particularly interested in that topic
since I'm politically against software patents). Do whatever works for
you.

But about public/internal and testing/keeping a clean API: I'm using a
different approach than InternalsVisibleTo. I keep all types public,
for the sake of making them easily testable, but store the "public
API" in the topmost namespace:

namespace MyLib {
// here goes "public API"
}

namespace MyLib.Internals {
// here goes "internal API", even though everything is marked with
keyword "public"
}

I've found it good enough in practice. "Internal" is only an
"attribute" of kinds anyway - one may view what I do as using the
namespace mechanism to "attribute" internal details instead of the
'internal' keyword.


> >
>



--
twitter.com/olofb
olofb.wordpress.com
olofb.wordpress.com/tag/english

sonof...@comcast.net

unread,
Sep 24, 2009, 10:06:54 AM9/24/09
to Moq Discussions
Okay, good news! I was able to get everything working finally.

The exception I mentioned in my last post was apparently caused by the
way I declared the InternalsVisibleTo attribute for
DynamicProxyGenAssembly2. The assembly containing my internal types
to which I added the attribute is not strongly-named (yet).
Nevertheless, I included the PublicKey in the attribute. When I
removed the PublicKey parameter from the attribute everything started
working!

So, I guess the moral of the story is:

a) We have to include the InternalsVisibleTo attribute for
DynamicProxyGenAssembly2 in the assembly containing
the internal types we want exposed to our tests.
b) Only include the PublicKey parameter if our assembly is strongly-
named

Thanks for all the help! Off to do some actual testing now..

Brad Wilson

unread,
Sep 24, 2009, 11:13:29 AM9/24/09
to moq...@googlegroups.com
Be aware that, since you are doing [InternalsVisibleTo] to an assembly that is not signed, anybody can now make an assembly named that and have access to the internal types.

David Taylor-Fuller

unread,
Sep 24, 2009, 9:08:39 PM9/24/09
to moq...@googlegroups.com
Yeah it seems like this only works when the assembly with the internal types or internal constructors is not signed. Otherwise, your still stuck with not being able to mock internal types or internal constructors.

http://code.google.com/p/moq/issues/detail?id=203

Kenneth Xu

unread,
Sep 24, 2009, 9:37:00 PM9/24/09
to moq...@googlegroups.com
Internal is to serve your OO design. Neither for preventing others
calling your code, nor for IP protection. I can well call any method,
including private ones via reflection regardless signed or not.

So making internal visible to your test assembly and DPBA2 is
perfectly fine and right thing to do.

> The assembly containing my internal types to which I added the attribute is not strongly-named (yet)

Sorry, I assumed strong-name a sure thing based on all those strict
rules you have described.

> Yeah it seems like this only works when the assembly with the internal types or internal constructors is not signed.

This is not true. See the link I have provided earlier. Honestly, I
didn't test myself with Moq but I do used it with another mocking
framework also based on same proxy generator: DP2.

sonof...@comcast.net

unread,
Sep 25, 2009, 3:28:28 PM9/25/09
to Moq Discussions
Actually, according to one of Moq's authors (and my testing), strong-
naming the assembly does not work. This is one of the reasons why we
aren't strong-naming the assembly yet. The other is because some of
the dependant assemblies provided by other teams are not strongly-
named. We will be stong-naming all of our assemblies prior to release
but until then, I have two legitimate reasons not to - unless I don't
want to be able to compile or test my app, of course.

As for the "internal" debate, I will argue that scoping has anything
to do with OO design. It does have to do with architecture and
establishing APIs between assemblies although I have heard someone say
that it is good OO practice to scope defensively, etc. but the
difference between public and internal is an API design choice and not
so much an OO matter - the object is the same either way and the types
inside the assembly see and treat it the same way. The only
difference is whether we expose it outside our assembly or not.

And, as for protecting my IP, I simply refer back to the fact that we
are obfuscating the code. And, I would suggest doing some research
before dismissing this as a way of securing our IP because we have
used this approach for several years, attempted to "hack" our code
using Reflector and reflection (amongst others) and found this
approach to be tremendously successful. After all, reflection only
gives you access to my interfaces, not the implementation of the
members. So while you may be able to exercise the members, you still
don't know the inner-workings. Furthermore, even if you get a
reference to my type using reflection, is type "a" or type "b" what
you are looking for and what does "a.x()" do?

Daniel Cazzulino

unread,
Sep 25, 2009, 3:45:18 PM9/25/09
to moq...@googlegroups.com
btw, I use (delay) signed assemblies with internals almost all the time without problems :|

/kzu

--
Daniel Cazzulino | Developer Lead | XML MVP | Clarius Consulting | +1 425.329.3471
Reply all
Reply to author
Forward
0 new messages