I'm getting the following error:
Test method: BootStrapperTest.Can_Create_Alert_Management_Object threw exception: Ninject.ActivationException:
Error activating IAlertManagement No matching bindings are available, and the type is not self-bindable.
Activation path:
1) Request for IAlertManagement
Suggestions:
1) Ensure that you have defined a binding for IAlertManagement.
2) If the binding was defined in a module, ensure that the module has been loaded into the kernel.
3) Ensure you have not accidentally created more than one kernel.
4) If you are using constructor arguments, ensure that the parameter name matches the constructors parameter name.
5) If you are using automatic module loading, ensure the search path and filters are correct.
Here is the test case that is causing this exception:
[TestInitialize]
public void Initialize()
{
BootStrapper.RegisterTypes();
}
[TestMethod]
public void Can_Create_Alert_Management_Object()
{
IAlertManagement alertManagementService = BootStrapper.Kernel.Get<IAlertManagement>();
Assert.IsNotNull(alertManagementService);
}
//This is the code that gets called in [TestInitialize]
public static void RegisterTypes()
{
if (!initialized)
{
Kernel.Bind(scanner => scanner.FromAssembliesMatching("MyCompany.MyProduct.*")
.SelectAllClasses()
.BindDefaultInterface());
Kernel.Unbind(typeof(IWcfServiceClient<>));
Kernel.Bind(typeof(IWcfServiceClient<>)).ToMethod(ctx =>
(ctx.Kernel.Get(typeof(WcfServiceClientProvider<>).MakeGenericType(ctx.GenericArguments)) as IProvider).Create(ctx));
}
initialized = true;
}
The above error is occurring in one of my unit tests on our build server but not on my development machine. I have 7 other tests almost identical to this one that pass on the build server and on my development machine but this is the only test that fails.
The IAlertManagement interface is coming from a dll called Core and the concrete type is coming from another dll called AlertManagement. I have both the Core dll and the AlertManagement dll included in my unit test project as project references. I have 7 or 8 other tests identical to this situation but this is the only one failing.
Any ideas would be appreciative.
The error occur because IAlertManagement is not binded with any concrete class.
Try to manually bind IAlertManagement.
public static void RegisterTypes()
{
if (!initialized)
{
Kernel.Bind(scanner => scanner.FromAssembliesMatching("MyCompany.MyProduct.*")
.SelectAllClasses()
.BindDefaultInterface());
//Try to add following line
Kernel.Bind<IAlertManagement>().To<ConcreteImplementationOfIAlertManagement>();
Kernel.Unbind(typeof(IWcfServiceClient<>));
Kernel.Bind(typeof(IWcfServiceClient<>)).ToMethod(ctx => (ctx.Kernel.Get(typeof(WcfServiceClientProvider<>).MakeGenericType(ctx.GenericArguments)) as IProvider).Create(ctx));
}
initialized = true;
}
I ended up resolving this by adding concrete references to the resolving types in my unit testing project. Just adding project references is not enough. This is how I'm doing this:
[TestClass]
public class AssemblyInitialize
{
/// <summary>
/// Method which gets executed once per unit test session. The purpose of this method is to reference any loosely coupled
/// assemblies so that they get included in the unit test session. If no code actually references a given assembly, even if its
/// technically a project reference, it will not be copied to the test output folder.
/// </summary>
[AssemblyInitialize]
public static void InitializeReferencedAssemblies(TestContext context)
{
List<Type> looselyCoupledTypes = new List<Type>
{
typeof(AlertManagement),
typeof(Naming),
};
looselyCoupledTypes.ForEach(x => Console.WriteLine("Including loosely coupled assembly: {0}",
x.Assembly.FullName));
}
}
The first thing that I would check is to ensure that the DLL that contains the implementation of IAlertManagement is getting copied to the proper directory on the build server so that the tests see it.
Another thing to try would be to move the kernel loading code to a ClassInitialize function instead of a TestInitialize, just to see if there is some sort of race condition or other related thing. I've seen random errors on build servers due to objects being disposed in a different order or sooner than would normally happen (involved Rx, TPL, and unobserved exceptions in my case). It may be that more tests are run in parallel on the build server than on the desktop.
Or it could be due partially to the fact that the server may be using Server GC. I don't know if forcing it to use Workstation GC would help or not but it might be worth a try.
Related
I am working on a small wpf application and one of the users is getting the following exception:
System.MethodAccessException:
Attempt by method "xxx.HttpConfirmation.Invoke()" to access method "System.Threading.Tasks.Task.get_CompletedTask()" failed.
at xxx.HttpConfirmation.Invoke()
at xxx.RequestPipeline.<ProcessQueuedRequests>d__11.MoveNext()
According to MSDN documentation, such exception is thrown in the following situations:
A private, protected, or internal method that would not be accessible from normal compiled code is accessed from partially trusted code by using reflection.
A security-critical method is accessed from transparent code.
The access level of a method in a class library has changed, and one or more assemblies that reference the library have not been recompiled.
Task.get_CompletedTask() is public since its introduction and I am also not using reflection to access the property.
I also don't think that there is a problem with code security/transparency since only one user is having this issue.
The exception is thrown at the Task.CompletedTask line:
public class HttpConfirmation
{
public static Task Invoke()
{
using (var client = new WebClient())
{
try
{
// Send the request and don't wait for the response.
client.UploadStringTaskAsync("http://sampleUrl.com", string.Empty);
}
catch
{
// ignore
}
}
return Task.CompletedTask;
}
}
Any ideas on what may cause the exception?
The problem was that the customer had .NET 4.5.2 installed and the program targeted .NET 4.6.
Though I still have no clue as to why exactly System.MethodAccessException was thrown as none of the 3 documented situations for throwing this exception did happen.
My current code situation is that I have in assembly A the following code:
public class Foo
{
public Foo()
{
CreateDebugMessage();
}
[Conditional("DEBUG")]
[DebuggerStepThrough]
private void CreateDebugMessage()
{
AddMessageType(MessageType.Debug, "Debug",
"/Company.App.Class;component/Images/image.png", Brushes.Green, false);
}
}
Some extra information is that I am using MEF and this method is called from the constructor. I have an assembly B (where I am importing assembly A) which depending on whether I am on DEBUG or RELEASE mode I want the Debug message to be created when I instantiate the class:
var foo = new Foo();
If I am on Debug mode I want the debug message to be created.
If I am on Release mode I DO NOT want the debug message to be created.
I thought the Conditional attribute would be better than the #iF DEBUG statement. This question showed me how WRONG I was! Since on runtime the method is never reached.
At this point I understand that the "#iF Debug" and "[Conditional("DEBUG")]" statements won't cut it for what I want to achieve.
Therefore my question is, how to make this scenario work?
The attribute works as it should, see Conditional Compilation in Referenced Assemblies. The attribute depends on the compilation symbols of the calling assembly. I tested and confirmed this: a method in an assembly with [Conditional("DEBUG")], compiled on Release, will only get called if the calling assembly is compiled in Debug. If this isn't the case for you, your code does not match your description.
The relevant part in your question is of course "This method is called from the constructor.". The attribute works for the direct caller, which in your case is the constructor of the containing class, which is Release.
You'll have to make it public and explicitly call the method:
public class Foo
{
public Foo()
{
}
[Conditional("DEBUG")]
[DebuggerStepThrough]
public void CreateDebugMessage()
{
AddMessageType(MessageType.Debug, "Debug",
"/Company.App.Class;component/Images/image.png", Brushes.Green, false);
}
}
var foo = new Foo();
foo.CreateDebugMessage();
I am in the process of replacing a COM+ hosted application with a .Net variant.
The steps I took are roughly:
Generate an Interop assembly of the old dll
Create a new class in C# .Net that derives from ServicedComponent and implements the IMyClass interface from the interop.
I have annotated the class with a [Guid("...")] and a [ProgId("...")] attribute to match the class in the old dll
The end result looks like this:
[ProgId("MyComponent")]
[Guid("...")]
public class MyClass : ServicedComponent, IMyClass
{
public MyClass()
{
}
public object Open(string arg1, string arg2)
{
/* trace arguments*/
}
public object Run()
{
/* implementation here */
}
public void Close()
{
return;
}
}
This assembly is installed on a remote machine using regsvcs.exe
Now most clients use code similar to this unittest code:
Type typeFromProgID = Type.GetTypeFromProgID("MyComponent", "remoteMachine", true);
dynamic comInstance = Activator.CreateInstance(typeFromProgID);
comInstance.Open(string.Empty, string.Empty);
comInstance.Run();
comInstance.Close();
This works perfectly, the .Net tracing on the remote machine tells me everything is working as it should. Other clients use code similar to this:
Type typeFromProgID = Type.GetTypeFromProgID("MyComponent", "remoteMachine", true);
MyClass comInstance = (MyClass)Activator.CreateInstance(typeFromProgID);
comInstance.Open(string.Empty, string.Empty);
comInstance.Run();
comInstance.Close();
The first line is the same and seems to work fine, the rest acts weird. The VS debugger shows the lines are being executed. The remoteMachine shows that no methods are being executed.
The last call to Close(), which actually just returns, throws an exception:
System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Result StackTrace:
at Interop.MyComponent.IMyClass.Close()
at UnitTestProject1.UnitTest1.temp()
What have I missed in my implementation to support this last (typed) scenario?
This sounds like mismatched metadata, e.g. marshaling is different between the one that happens with the original type library and the one that happens with your server registered .NET assembly.
My guess is that the untyped case runs well because it depends solely on IDispatch, which .NET implements quite well, but the typed test fails (and I'm surprised it doesn't fail earlier) because of this mismatch.
this is a follow on from this question I asked a while ago:
Assembly.GetExecutingAssembly() performance
this solution seemed perfect. Now I've just gottent around to implementing it and it doesn't work. I get a System.TypeInitializationException thrown, the inner exception is the good old, Object reference not set to an instance of an object. Now I'm not sure why it's not working. My guess is that the static readonly property is instanticating before the Assembly class or something?
Can anybody shed any light on why this is happening, any fixes, other than not use a readonly as this is obvious, would also be welcome though not necessarily expected!
Here's the code:
public class VersionHelper
{
private static readonly Version _applicationVersion = Assembly.GetEntryAssembly().GetName().Version;
public static string GetVersionText()
{
return string.Format("Version: {0}-{1}", _applicationVersion, Environment.MachineName.Substring(5));
}
}
Called:
protected void Page_Load(object sender, EventArgs e)
{
lblVersion.Text = VersionHelper.GetVersionText();
}
Just to explain if I do it this way it works:
public class VersionHelper
{
public static string GetVersionText()
{
Assembly web = Assembly.GetExecutingAssembly();
AssemblyName webName = web.GetName();
return string.Format("Version: {0}-{1}", webName.Version, Environment.MachineName.Substring(5));
}
}
The exception doesn't have anything to do with the fact that the property is readonly or not. The problem is that you are calling Assembly.GetEntryAssembly() in a ASP.NET context, and apparently that doesn't work well together.
The other option that you have also does not use this method, it uses Assembly.GetExecutingAssembly. If you change your first sample so it uses Assembly.GetExecutingAssembly, than you will see that it runs fine.
I do not have any real references, but you can check this question, and in particular the comments beneath the question.
It also has a solution on how to get an entry assembly in a ASP.NET context.
Assembly.GetEntryAssembly is not reliable, specifically it will return NULLif the application started in an unmanaged context instead of a managed context. The result must be null checked..
For example, if an unmanaged application creates an instance of a COM component written in C#, a call to the GetEntryAssembly method from the C# component returns NULL, because the entry point for the process was unmanaged code rather than a managed assembly.
whereas GetExecutingAssembly just gets the assembly that contains the code that is currently executing.
while To get the assembly that contains the method that called the currently executing code, you should use GetCallingAssembly.
I'm new to Nunit testing and I wanted to test the following constructor:
public class IngredientDAONHibernate : NutritionLibrary.DAO.IngredientDAO
{
private Configuration config;
private ISessionFactory factory;
public IngredientDAONHibernate()
{
try
{
config = new Configuration();
config.AddClass(typeof(NutritionLibrary.Entity.Ingredient));
config.AddClass(typeof(Entity.Nutrient));
config.AddClass(typeof(Entity.NutrientIngredient));
factory = config.BuildSessionFactory();
}
catch (Exception e)
{
// logger.Error("Exception Occured", e);
}
}
The test stub is as follows:
[TestMethod()]
public void IngredientDAONHibernateConstructorTest()
{
IngredientDAONHibernate target = new IngredientDAONHibernate();
}
Could someone help me with some tips as to how I can get started? Thanks!
I would suggest that you don't catch all the exceptions, but, if there are certain you want to catch and ignore then just do those, otherwise it is harder to tell if you have a problem.
I tend not to test the constructor, unless it is doing quite a bit, and it will be obvious if there is a problem when doing the other unit tests, as, if the constructor fails you should see by the exception, and by the fact that all the tests will be failing.
If you want to test this constructor, limit your exceptions and just ensure that there is no exception when you run the test.
Let me turn the question back on to you.. How do you know if the constructor executed as intended ?
Normally constructors are trivial.. but here it seems that you have some third party lib interfacing code that you need some confidence with.
If you only want to test that there are no exceptions raised from within the constructor... then Extract a logger interface. Now in your test pass in a mock logger (a fake can also suffice), which should help you to sense if an exception was logged.
[TestMethod()]
public void IngredientDAONHibernateConstructorTest()
{
_errorLogged = false;
ILogger logger = this; // make test fixture implement the logger interface ; self-shunt
IngredientDAONHibernate target = new IngredientDAONHibernate(logger);
Assert.IsNotNull(target);
Assert.IsFalse(_errorLogged,
String.Format("ERROR! Constructor has thrown {0}", _loggedException) );
}
bool _errorLogged;
Exception _loggedException;
public void Error(string message, Exception e)
{
_errorLogged = true;
_loggedException = e;
}
Like everyone else, I would caution against catching Exception. The documentation should tell you what exceptions can be expected and you could write specific Catch clauses for each of them, if that made sense.
Leaving that aside, your tests should verify that your objects are in the state you expect. Given what we can see, all you can do is test that it's not null. If you can force an exception, you could test that the logger gets the exception message. If there was a public property that gave access to your factory, you would want to test that (not null, perhaps other things) and likewise with the config field. For that, if you have access to the added classes, you could test not null and count==3. If the exact objects are important, you could test that they are there. It's always tricky to decide how much to trust third-party stuff. Generally, I do unless I get evidence that I shouldn't.
When it comes to testing methods, test for each parameter whatever is possible. So, for a string, test null and emptystring plus relevant (valid and invalid) values. If you're expecting alphanumerics, test special chars as well. If data has boundaries test values on and either side of the boundary(ies) plus typical values. E.g. if you're expecting an int between 0 and 10, test -1, 0, 1, 5, 9, 10, 11. It only takes seconds to write but it can save you hours in two years when you're trying to fix a bug.