Moles can be used in two ways:
<Moles xmlns="http://schemas.microsoft.com/moles/2010/">
<Assembly Name="Samples.Moles"/>
</Moles>
What I noticed is that using the dynamic assembly doesn't require the test project to declare 'moled assemblies' attributes. This reduces the overhead, and a developer need only decorate each test method with the host type for moles; but further testing doesn't need to keep track of what types to instrument.
Looking at the auto-generated code (using a disassembler) in the molesassemblies, it is easy to find that the needed instrumentation attributes. However, trying to write my own 'mole assembly', essentially replacing the autogenerated one, doesn't work and the runtime complains that my type needs to be instrumented. I am curious what I'm missing.
I noticed that the autogenerated moles code declared the necessary MoledAssembly attributes. But in my tests, the test project seems to have to declare this property; it can't be declared by a referenced assembly to the project. However, in the case with the autogenerated assembly, it APPEARS the attribute can be declared "outside". This is my assumption based what I can see with disassembling the autogenerated moles dll; I cannot find any other difference. However, as I'm trying to explain, copying all the code (and attributes) from the disassembled autogenerated moles dll and building my own referenced assembly fails at runtime saying I have not marked the needed assembly-in-test to be instrumented (i.e. marked with the MoledAssembly) - tho it has, simply in my referenced asssembly.
-- update
At this point (likely due to my misunderstanding of what my code is missing) I feel we need to be very specific about what assembly has what. Let's say we have 4 dlls:
MoledAssembly
.*.moles
file in your project. References the 4th dll, (see #4) Sealed
. Declares [assembly: MoledAssembly("Sealed")]
. Note that I'm trying to accomplish manual mole injection without this dll - it's only a conceptual reference or to be used in our discussion or troubleshooting.Moles.dll
.In answers/comments/questions - let's refer to each part according to this list.
The assembly attribute is required, when using moled assemblies that are not automatically generated. The Moles Tools for Visual Studio automatically alert the compiler to the presence of generated assemblies, out of necessity.
When adding a Moles assembly via Visual Studio, the mole assembly is not generated until the project is built. Furthermore, it is impossible to include an assembly attribute for an assembly that does not already exist. Doing so will cause the compiler to fail. Therefore, it is necessary for Moles to also dynamically add commands to the compiler command line, to generate the moled assemblies, and then properly reference them from the project.
When using a manually-generated, moled assembly, it is necessary to include an assembly attribute, because the Moles tools is unaware of its presence by virtue of the assembly not being auto-generated. The programmer has to do the job for Moles.
If you want to go so far, you may employ code generation, before the compiler engages. PERL can easily inject the necessary assembly attribute, where needed. When the compiler receives the code, it will already have the attribute(s) injected.
An Experiment to Back my Answer:
I was able to reproduce your issue. I was also able to resolve the problem, by adding an assembly attribute, below the using statement block. I took the following steps, to build my sample application:
Created the following method, in Class1:
public string TestString() { return "Original value."; }
Created a test project (TestProject1), by right-clicking the TestString method declaraction, and then selecting Create Unit Tests... (Lazy, I know.)
Test method TestProject1.Class1Test.TestStringTest threw exception: Microsoft.Moles.Framework.Moles.MoleNotInstrumentedException: The System.String ClassLibrary1.Class1.TestString() was not instrumented To resolve this issue, add the following attribute in the test project:
using Microsoft.Moles.Framework; [assembly: MoledAssembly(typeof(ClassLibrary1.Class1))]
I added the recommended assembly attribute to the file. After doing so, the test method ran successfully. I suspect the compiler is automatically referencing generated moled assemblies, removing the need for the assembly attribute. I tried copying the MoleClassLibrary binaries to the MolesAssemblies directory and creating a MoleClassLibrary.moles file, to test this theory. The test passed only when I included the assembly attribute. This result is inconclusive to my hypothesis.
Here's the code for Class1Test.cs:
using ClassLibrary1;
using Microsoft.Moles.Framework;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MoleClassLibrary;
[assembly: MoledAssembly(typeof(ClassLibrary1.Class1))]
namespace TestProject1
{
[TestClass()]
public class Class1Test
{
[TestMethod()]
[HostType("Moles")]
public void TestStringTest()
{
var target = new Class1();
var expected = "Mole value.";
string actual;
MClass1.AllInstances.TestString = value => expected;
actual = target.TestString();
Assert.AreEqual(expected, actual);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With