Microsoft Fakes: Trying to shim a class but dependencies are still there - c#

Ok, so here's the deal: I have a complex, heavily dependent class LegacyClass that I'd like to shim so that I get rid of all its dependencies while unit testing other parts of the code base. That class creates dependencies already inside its default constructor, so I need to override it with something with no external dependencies, say, with an empty default constructor. And this is what I'm trying to do (using the Visual Studio 2013 Professional Test Framework):
using System;
using Microsoft.QualityTools.Testing.Fakes;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace MyApp_Unit_Tests {
[TestClass]
public class UnitTest1 {
[TestMethod]
public void TestInstantiation1() {
using (ShimsContext.Create()) {
MyNamespace.Fakes.ShimLegacyClass.Constructor = x => { };
var legacyClassInstance = new MyNamespace.Fakes.ShimLegacyClass();
var sut = new MyNamespace.Gui.ViewModels.MainWindowViewModel(legacyClassInstance);
}
}
}
}
However, this does not work. When MainWindowViewModel is instantiated, for some reason all the same external dependencies are still required as with using the original class! Why?
The exception I'm getting, though, is System.BadImageFormatException, so I probably have some confusion about the target CPU settings, too, but anyway the root cause is that it's attempting to load the external DLL referred to only in the original (non-shimmed) legacy class in its default constructor, while I think it no longer should.
Obviously I've been misunderstood, but where's the mistake? Can I not override default constructors, after all, even with using Shims, or is my approach just wrong? What am I missing?
Thanks a million in advance for any advice!
-Seppo

I had same problem and I solved it maybe this approach going to help you
using (ShimsContext.Create())
{
LegacyClass obj=new LegacyClass();
ShimLegacyClass shimobj=new ShimLegacyClass(obj);
//
// modify every thing you want on shimobj
//
shimobj.InstanceBehavior = ShimBehaviors.Fallthrough;
//rest of test
}
This approach helps you to break dependencies in every part you want and keep the rest same as main class

Related

StackExchange.Precompilation - How can I unit test precompilation diagnostics?

Background
I'm using StackExchange.Precompilation to implement aspect-oriented programming in C#. See my repository on GitHub.
The basic idea is that client code will be able to place custom attributes on members, and the precompiler will perform syntax transformations on any members with those attributes. A simple example is the NonNullAttribute I created. When NonNullAttribute is placed on a parameter p, the precompiler will insert
if (Object.Equals(p, null)) throw new ArgumentNullException(nameof(p));
at the beginning of the method body.
Diagnostics are awesome...
I would like to make it difficult to use these attributes incorrectly. The best way I have found (aside from intuitive design) is to create compile-time Diagnostics for invalid or illogical uses of attributes.
For example, NonNullAttribute does not make sense to use on value-typed members. (Even for nullable value-types, because if you wanted to guarantee they weren't null then a non-nullable type should be used instead.) Creating a Diagnostic is a great way to inform the user of this error, without crashing the build like an exception.
...but how do I test them?
Diagnostics are a great way to highlight errors, but I also want to make sure my diagnostic creating code does not have errors. I would like to be able to set up a unit test that can precompile a code sample like this
public class TestClass {
public void ShouldCreateDiagnostic([NonNull] int n) { }
}
and confirm that the correct diagnostic is created (or in some cases that no diagnostics have been created).
Can anyone familiar with StackExchange.Precompilation give me some guidance on this?
Solution:
The answer given by #m0sa was incredibly helpful. There are a lot of details to the implementation, so here is the unit test actually looks like (using NUnit 3). Note the using static for SyntaxFactory, this removes a lot of clutter in the syntax tree construction.
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using NUnit.Framework;
using StackExchange.Precompilation;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
namespace MyPrecompiler.Tests {
[TestFixture]
public class NonNull_CompilationDiagnosticsTest {
[Test]
public void NonNullAttribute_CreatesDiagnosticIfAppliedToValueTypeParameter() {
var context = new BeforeCompileContext {
Compilation = TestCompilation_NonNullOnValueTypeParameter(),
Diagnostics = new List<Diagnostic>()
};
ICompileModule module = new MyPrecompiler.MyModule();
module.BeforeCompile(context);
var diagnostic = context.Diagnostics.SingleOrDefault();
Assert.NotNull(diagnostic);
Assert.AreEqual("MyPrecompiler: Invalid attribute usage",
diagnostic.Descriptor.Title.ToString()); //Must use ToString() because Title is a LocalizeableString
}
//Make sure there are spaces before the member name, parameter names, and parameter types.
private CSharpCompilation TestCompilation_NonNullOnValueTypeParameter() {
return CreateCompilation(
MethodDeclaration(ParseTypeName("void"), Identifier(" TestMethod"))
.AddParameterListParameters(
Parameter(Identifier(" param1"))
.WithType(ParseTypeName(" int"))
.AddAttributeLists(AttributeList()
.AddAttributes(Attribute(ParseName("NonNull"))))));
}
//Make sure to include Using directives
private CSharpCompilation CreateCompilation(params MemberDeclarationSyntax[] members) {
return CSharpCompilation.Create("TestAssembly")
.AddReferences(References)
.AddSyntaxTrees(CSharpSyntaxTree.Create(CompilationUnit()
.AddUsings(UsingDirective(ParseName(" Traction")))
.AddMembers(ClassDeclaration(Identifier(" TestClass"))
.AddMembers(members))));
}
private string runtimePath = #"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\";
private MetadataReference[] References =>
new[] {
MetadataReference.CreateFromFile(runtimePath + "mscorlib.dll"),
MetadataReference.CreateFromFile(runtimePath + "System.dll"),
MetadataReference.CreateFromFile(runtimePath + "System.Core.dll"),
MetadataReference.CreateFromFile(typeof(NonNullAttribute).Assembly.Location)
};
}
}
I figure you want to add you diagnostics before the actual emit / compilation, so the steps would be:
create your CSharpCompilation, make sure it has no diagnostic errors before going further
create an BeforeCompileContext, and populate it with the compilation and an empty List<Diagnostic>
create an instance of your ICompileModule and call ICompileModule.BeforeCompile with the context from step 2
check that it contains the required Diagnostic

How to use ITestEventListener in NUnit 3?

I want to add a custom test reporter to NUnit. I already did it with NUnit2, but I now need to use NUnit3.
To implement the reporter, I need to get various events from the framework, like start, end and failure of tests.
In NUnit2 I used NUnitHook to register my EventListener and it worked pretty good.
In NUnit3 I need to use the extension point mechanism, but when I add the extension point to the project, VisualStudio (2012 ultimate) immediately fails to discover the NUnit tests.
[TypeExtensionPoint(Description = "Test Reporter Extension")]
public class MyTestEventListener : ITestEventListener
{
public void OnTestEvent(string report)
{
Console.WriteLine(report);
}
}
If I remove the ITestEventListener implementation declaration from the class, it rediscovers the tests perfectly.
[TypeExtensionPoint(Description = "Test Reporter Extension")]
public class MyTestEventListener //: ITestEventListener
{
public void OnTestEvent(string report)
{
Console.WriteLine(report);
}
}
Am I doing something wrong? is there a better way to achieve it?
You don't say where you are putting this code, but I am suspecting it's in your test assembly. If so, that's not where it belongs. NUnit engine extensions get installed into the NUnit engine, so they need to be in a separate assembly. Once you have a separate assembly, you need to tell the engine where it is. Currently, you do this by creating a file of type .addins in the same directory as the engine. (You could modify the existing file, but that introduces maintenance problems in the future)
A future release will have an easier way to install addins, but they will continue to be entirely separate from your tests.
A further problem is that you are using TypeExtensionPointAttribute. I didn't notice this originally in your code and it's probably the biggest error so I'm adding this info now.
An "ExtensionPoint" is the thing you are extending. NUnit defines ExtensionPoints, while you create Extenisons to extend them. TypeExtensionPointAttribute is used inside NUnit to define extension points. It's not used by you. You use the ExtensionAttribute to define your extension.
Your extension should be defined something like this:
[Extension(Description = "Test Reporter Extension", EngineVersion="3.4")]
public class MyTestEventListener : ITestEventListener
{
public void OnTestEvent(string report)
{
Console.WriteLine(report);
}
}
You don't say what version of NUnit you are running. Test Listeners are only supported beginning with version 3.4. The EngineVersion property above is purely documentary at this point, because 3.4 is also the first version to recognize it.
There is a new writeup in the NUnit docs that may be helpful: https://github.com/nunit/docs/wiki/Writing-Engine-Extensions

Suggestion for ServiceStack.NET

The suggested way of using ServiceStack.NET with Silverlight is to use the Linked-Project addon. This enables two synchronous Projects and their sources, one for Silverlight, one for .NET 3.5+.
But when it comes to validation, this gets a bit annoying.
ServiceStack is using FluentValidation, which is cool. But it has changed the namespace.
So I end up with:
using MyNamespace.Model;
// HERE ----------------------------
#if SILVERLIGHT
using FluentValidation;
#else
using ServiceStack.FluentValidation;
#endif
//TO HERE------------------------
namespace HR.RoBP.Contracts.Validators.Model
{
public class CustomerValidator : AbstractValidator<Customer>
{
public CustomerValidator()
{
RuleFor(r => r.Name).NotEmpty().NotNull();
}
}
}
This is not much, but it gets really annoing when writing a new validator each time. I often forget it, compile, have errors, fix it.
I know there is something changed in FluentValidation on ServiceStack.NET.
But must it be in a seperate Namespace?
I think its in the interest of servicestack to keep code files clean.
But using the the same validation on client and server forces me to do this.
If there is a elegant way to fix this issue, I would love to hear about it.
You unfortunately can't set a project-wide namespace alias. You could however try to write a template for your validator class that has that boilerplate code built in, and you can easily click Add -> New Item -> Your Validator Template.

Dependency Injection - Choose DLL and class implementation at runtime through configuration file

I've an API DLL (API.dll, for example) which, in addition to many other thinks, makes available an abstract class (AbstractClass).
Now making use of that AbstractClass I've implemented it on two different dlls:
First.API.Implementation.dll with ConcreteImplementation1
Second.API.Implementation.dll with ConcreteImplementation2
Both ConcreteImplementation1 and ConcreteImplementation2 are implementation of the same abstract class.
What I want is an application where I can choose which of those two dlls to use and, through that, choose which implementation to use without the user having to change anything within the code and, if possible, without stopping the application.
Some configuration file where I can bring the application to use whatever implementation I want. Something like:
<appconfiguration>
<implementation_to_use>
<dll>First.API.Implementation.dll</dll>
<class>ConcreteImplementation1</class>
</implementation_to_use>
</appconfiguration>
I know near to nothing about dependency injection, apart from its concept, but I guess thats the perfect fit for this task.
I've researched several DI/IoC libraries but I'm not familiar with all the concepts and names. I can use whatever library I want. For what I can say these are the most used: StructureMap, Ninject and Sprint.NET
Moreover, apart from all the dlls and implementation I need to indicate a file to be used by that application. Can I indicate its path in that same file?
I just need some tips and directions to implement such a thing. Some examples using one of those libraries, would be awesome.
Thanks.
To get you started using StructureMap, create a console application, include in it:
structuremap.config:
<?xml version="1.0" encoding="utf-8" ?>
<StructureMap MementoStyle="Attribute">
<DefaultInstance
PluginType="DemoIoC.AbstractBase,DemoIoC"
PluggedType="DemoIoC.ConcreteImplementation1,DemoIoC"
Scope="Singleton" />
</StructureMap>
The PluginType and PluggedType attributes are "FullyQualifiedClassName,AssemblyName"
By default it will look for assemblies in the executable folder, I'm not sure how you would specify another location for the assemblies
There are plenty of options for Scope, e.g. Singleton, Transient, etc
Program.cs:
namespace DemoIoC
{
using System;
using StructureMap;
public static class Program
{
public static void Main(string[] args)
{
// here you initialize structuremap from the config file.
// You could probably use a FileSystemWatcher to reinitialize
// whenever the structuremap.config file changes
ObjectFactory.Initialize(x =>
{
x.UseDefaultStructureMapConfigFile = true;
});
var concrete = ObjectFactory.GetInstance<AbstractBase>();
concrete.Method1();
Console.ReadKey(true);
}
}
}
AbstractBase.cs:
namespace DemoIoC
{
public abstract class AbstractBase
{
public abstract void Method1();
}
}
ConcreteImplementation1.cs:
namespace DemoIoC
{
using System;
public class ConcreteImplementation1 : AbstractBase
{
public override void Method1()
{
Console.WriteLine("Called ConcreteImplementation1");
}
}
}

Having trouble getting started with Moq and Nunit

Banging my head against a wall trying to get a really simple testing scenario working.
I'm sure I'm missing something really simple!
Whatever I do, I seem to get the following error from the NUnit gui when running a test against my DLL:
System.TypeLoadException : Type 'Castle.Proxies.ITestProxy' from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is attempting to implement an inaccessible interface.
Now I've seen reference to this error in heaps of places when looking in Stack Overflow and elsewhere, but the solution I keep finding doesn't seem to help. And I'm not even using an internal interface at this stage! The solution I see around the place is too put the following line in AssemblyInfo.cs
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
I'm using:
Visual Studio 2010 Professional
c# 4.0
Moq 4.10810.8 Beta (bin deployed)
NUnit 2.5.5 (Installed in GAC)
To recreate this error, all I need to do is:
Create a new class library project
Reference Moq and Unit (as above)
Create an interface. I've called my interface ITest, made it public, and it has one method which is 'string TestMethod();'. Am doing this in the local project for simplicity.
Create a class called 'Testing', decorated with [TextFixture] and a test method called 'TestMethod' decorated with [Test]
Build the project, then run NUnit against the resulting dll in the Debug folder.
Here's the contents of my test class
namespace MoqTest {
[TestFixture]
public class Testing {
[Test]
public void TestMethod() {
var testMock = new Mock<ITest>();
testMock.Setup(x => x.TestMethod()).Returns("String val");
var xyz = testMock.Object;
Assert.AreEqual(1, 1);
}
}
}
---- UPDATE ---
After changing Moq version from 4.10810.8 to 4.0.10501.6 everything works fine!
The following test passes for me:
public interface ITest { string TestMethod(); }
public class Testing
{
[Test]
public void TestMethod()
{
var testMock = new Mock<ITest>();
testMock.Setup(x => x.TestMethod()).Returns("String val");
var xyz = testMock.Object;
Assert.AreEqual(1, 1);
}
}
If your interface is public and in the same assembly, there really should be no problem. I suspect that you just missed an accessibility keyword somewhere, as a non-public interface does provoke a runtime error because the proxying assembly will be unable to instantiate a type based on it.
Probably the best thing to do is start with the code I've provided and change one thing at a time until it matches your failing code. If you run your test in between each change, I presume you'll find what was missing.
If you do go back to an internal interface, note that your InternalsVisibleTo statement must be in the same assembly as your internal interface, not your test assembly. Also note that if your assembly is strongly named you may need to add a public key fingerprint to your InternalsVisibleTo statement as described in MSDN.
Yeah I had the same issue with Moq.4.0.10810.8 for NET40... When I downgraded to version 4.0.10531.7 everything went green again!
I'm using 4.10.1 now, and I got this same issue. I tried downgrading to 4.10.0, but to no avail.
I finally found that, although the interface I was using was marked as public, it was in a class without a modifier. I found 2 things got it to work:
1) Pull the interface outside of the class. Because the class was no longer making the interface internal, it became accessible to the assembly.
2) Mark the class public. With all parts of the path to the interface being marked public, the assembly had no trouble accessing.
These strategies worked in both 4.10.0 and 4.10.1.

Categories

Resources