Moles and internal classes
Asked Answered
M

1

1

We are using Moles currently to test some code that interacts with a 3rd party library. The library was not setup for testing very well (hence the need for moles) and the issue that I am running into is that they only publicly expose a single abstract class. The concrete implementations are internal to the 3rd party library.

The issue I am facing is that when trying to create an instance of the public type it is requesting a concrete type from moles, but moles isn't generating moles objects for those types because they are internal.

Under the moles documentation the way to expose the internals is to add the InternalsVisibleTo attribute in the AssemblyInfo.cs file. However this is to expose my assembly internals for moles to use, since these are 3rd party libraries with already created assemblies I don't know how to go about making those internals visible so that moles can use them.

Anyways, any help on this would be great. I will settle for an integration test is that is the only solution, but hope to not have to go to that point.

Manvel answered 11/11, 2011 at 22:36 Comment(2)
Does your testing need to cover testing for the 3rd party library too?Submission
No I don't care about the 3rd party libraries directly, this is just to care about testing my code that utilizes the 3rd party tools.Manvel
S
5

An approach I've used very successfully is to roll my own proxy classes for unmockable third party types. E.g. I want to take a dependency on a type ThirdParty.Foo which is sealed/static/has no interface/etc. Instead, I create a library called ThirdParty.Proxies and add a concrete type Foo and an interface IFoo to this new library. The interface IFoo exposes members equivalent to all those which I require from the underlying ThirdParty.Foo type and the concrete type ThirdParty.Proxies.Foo implements those members by doing nothing other than forwarding method calls to the underlying third party library. ThirdParty.Proxies is excluded from unit testing and code coverage. In my consuming assembly, I take a dependeny only on ThirdParty.Proxies and, specifically, I only take a dependency on IFoo. This way I can mock this dependency easily and attain 100% code coverage for my consuming assembly.

This is a little more work, and it's similar to what Moles does for you dynamically, but once done it can be re-used everywhere and your unit tests will be faster by not incurring the overhead of Moles.

Swithin answered 11/11, 2011 at 22:53 Comment(3)
I, too, have used this methodology. It works very well, to resolve your issue.Viceroy
I like the idea of completely ridding myself of moles, the one thing would be to assume that the Proxy classes themselves (since they are just adapters) are not testable other then integration testing. I see you say you don't include that code in your coverage calculations but has that ever been an issue for you?Manvel
we find that excluding the proxy assemblies is acceptable. They are very simple types which consist of nothing other than one line method forwarders and, as you say, it's good to ensure they have a reasonable level of coverage by integration tests. A code review will also usually pick out any small typos or mistakes. You'll find that, once you've written a few proxies, there are 3 or 4 'formulae' for writing them, depending on whether your proxied type is sealed/static/etc. and you'll be very confident adding new ones. In fact, so far, we have never found a bug in our proxy types.Swithin

© 2022 - 2024 — McMap. All rights reserved.