Comments (15)
I've noticed that Assert
statements tend to break Pose. I'm currently looking into it, but in the meantime you can do this instead:
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Pose.Tests.Fails
{
[TestClass]
public class ShimFails
{
public class MyClass
{
public int MyProperty { get; set; }
}
[TestMethod]
[ExpectedException(typeof(NullReferenceException))]
public void ShimConstructor()
{
Shim ctorShim = Shim.Replace(() => new MyClass())
.With(() => new MyClass { MyProperty = 10 });
int prop = 0;
PoseContext.Isolate(() =>
{
prop = new MyClass().MyProperty;
}, ctorShim);
// this line breaks the Shim
Assert.AreEqual(10, prop);
}
}
}
from pose.
@tjrobinson if the client test actually calls the code in the controller instead of making an actual http request you should be fine. I'm looking into this as well as the other issues you raised. Have you been able to get some other tests to work with Pose?
from pose.
Also what's happening here is that a stub is passing a null method to be rewritten.
from pose.
if the client test actually calls the code in the controller instead of making an actual http request you should be fine
Yep, I think it would be. Unfortunately these are deliberate integration tests to check the API layer. I have other tests for the MediatR commands/queries that the controllers use.
I haven't got any other tests working with Pose yet as I've not tried yet.
from pose.
Alrighty. Do try if/when you can and let me know if you run into anymore problems. Thanks
from pose.
@tjrobinson I'm curious, what made you think the error was from Pose.Helpers.StubHelper.GetMatchingShimIndex
? The exception stack trace doesn't include it. Also I notice you're using Pose directly in source code form, you can update your local with this branch https://github.com/tonerdo/pose/tree/stub-enhancements and try the code again. Paste the exception output here, I added a few things to make it easier to track the origin of exceptions like this
from pose.
@tonerdo GetMatchingShimIndex
was coming up in the stack trace when I was trying a few things out earlier on though as you noticed, it's not in the one above. I think it's a different trace because I tried to simplify the failing scenario and ended up with a variation on the problem. Sorry I don't have the earlier stack trace anymore.
I can't try the stub-enhancements
branch at the moment but will if I get time at some other point .
from pose.
@tonerdo I have the same Null Reference Exception popping up. And tracked it down to GetRuntimeMethodForVirtual
The following code throws the null reference exception.
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Pose.Tests.Fails
{
[TestClass]
public class ShimFails
{
public class MyClass
{
public int MyProperty { get; set; }
}
[TestMethod]
[ExpectedException(typeof(NullReferenceException))]
public void ShimConstructor()
{
Shim ctorShim = Shim.Replace(() => new MyClass())
.With(() => new MyClass { MyProperty = 10 });
PoseContext.Isolate(() =>
{
// this line breaks the Shim
Assert.AreEqual(10, 10);
}, ctorShim);
}
}
}
It was trying to find: RuntimeType.GetTypeInfo
but the actual method name was System.Reflection.TypeInfo.System.Reflection.IReflectableType.GetTypeInfo()
. I tried to return that but it didn't seem to help.
After that I was getting confused.
Hope this helps.
from pose.
I tried looking into the issue. Unfortunately I haven't found a solution yet. I tried the following:
- The
RuntimeMethodForVirtual
returns null after whichGetIndexOfMatchingShim
will fail.
In theAssert
caseType
isSystem.RunTimeType
andmethodInfo
isGetTypeInfo
public static MethodInfo GetRuntimeMethodForVirtual(Type type, MethodInfo methodInfo)
{
BindingFlags bindingFlags = BindingFlags.Instance | (methodInfo.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic);
Type[] types = methodInfo.GetParameters().Select(p => p.ParameterType).ToArray();
return type.GetMethod(methodInfo.Name, bindingFlags, null, types, null);
}
- One solution I tried was to find the method in anotherway. ie:
public static MethodInfo GetRuntimeMethodForVirtual(Type type, MethodInfo methodInfo)
{
BindingFlags bindingFlags = BindingFlags.Instance | (methodInfo.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic);
Type[] types = methodInfo.GetParameters().Select(p => p.ParameterType).ToArray();
MethodInfo foundMethod = type.GetMethod(methodInfo.Name, bindingFlags, null, types, null);
if (foundMethod == null)
{
MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foundMethod = methods.FirstOrDefault(i => i.Name.EndsWith(methodInfo.Name));
return foundMethod;
}
return foundMethod;
}
The name of the method it find is: "System.Reflection.IReflectableType.GetTypeInfo" (this is not the FullName
, but the normal Name
.
But running this results in crashing the debugger.
- Next I tried to simply run the original method whenever
RuntimeMethodForVirtual
returned NULL but I that resulted in a invalid program.
from pose.
@jonkeda Problem with Assert.AreEqual caused by explicit implementation of IReflectableType.GetTypeInfo() in
class System.Reflection.IntrospectionExtensions
{
public static TypeInfo GetTypeInfo(this Type type)
{
if (type == (Type) null)
throw new ArgumentNullException(nameof (type));
return ((IReflectableType) type).GetTypeInfo();
}
}
this is the reason why
public static MethodInfo GetRuntimeMethodForVirtual(Type type, MethodInfo methodInfo)
returns null
there is a case to reproduce this issue
interface IMyTest
{
int ExplicitMethod();
}
class MyTest : IMyTest
{
int IMyTest.ExplicitMethod() => 1;
}
[TestMethod]
public void TestExplicit()
{
Shim shim = Shim.Replace(() => Is.A<IMyTest>().ExplicitMethod()).With((IMyTest t) => 42);
var r = new MyTest();
PoseContext.Isolate(() => { var foo = ((IMyTest)r).ExplicitMethod(); }, shim);
}
I haven't solve this problem yet but if your know an elegant and easy way to get explicitly implemented members, i would like to hear about it
from pose.
@Daxaker It isn't anywere near elegant, but I do have a working 'solution'.
- if the method isn't found then look if a method exists which name ends with the method to find. (brrr)
public static MethodInfo GetRuntimeMethodForVirtual(Type type, MethodInfo methodInfo)
{
BindingFlags bindingFlags = BindingFlags.Instance | (methodInfo.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic);
Type[] types = methodInfo.GetParameters().Select(p => p.ParameterType).ToArray();
var method = type.GetMethod(methodInfo.Name, bindingFlags, null, types, null);
if (method == null)
{
MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
MethodInfo foundMethod = methods.FirstOrDefault(i => i.Name.EndsWith(methodInfo.Name));
return foundMethod;
}
return method;
}
- Expand the
SignatureEquals
to also look for interfaces.
private static bool SignatureEquals(Shim shim, Type type, MethodBase method)
{
if (shim.Type == null || type == shim.Type)
return $"{shim.Type}::{shim.Original.ToString()}" == $"{type}::{method.ToString()}";
if (type.IsSubclassOf(shim.Type))
{
if ((shim.Original.IsAbstract || !shim.Original.IsVirtual)
|| (shim.Original.IsVirtual && !method.IsOverride()))
{
return $"{shim.Original.ToString()}" == $"{method.ToString()}";
}
}
if (shim.Type.IsAssignableFrom(type))
{
if ((shim.Original.IsAbstract || !shim.Original.IsVirtual)
|| (shim.Original.IsVirtual && !method.IsOverride()))
{
return $"{shim.Original.ToString()}" == $"{method.ToString()}"
|| method.Name.EndsWith(shim.Original.Name) ;
}
}
return false;
}
This code works for your testcase. But isn't very elegant or fail safe.
from pose.
@Daxaker many thanks for this repro. Will take a look and work on a fix
from pose.
@tonerdo Glad to be helpful
from pose.
My issue indeed had to do with calling xUnit Assert() method within the Isolate() function. Moving my assert methods out fixed the error for me.
from pose.
Has this problem fixed in a new distribution?
Or is it a normative way to act in isolate context and to assert outside?
from pose.
Related Issues (20)
- how to shim a constructor with parameters?
- Offer to make public Shim constructor HOT 1
- Pose not compatible with Code Coverage tools?
- Can we use Pose with Moq?
- Common Language Runtime detected an invalid program. HOT 1
- Async-await HOT 3
- Reviving this project HOT 16
- Question : Make my function throw an exception
- shim for DateTime.UtcNow not working HOT 5
- Issue with DateTime.Now HOT 1
- Bug with a test app
- Issue with .Net static methods like File.Exists
- .NET 6.0 HOT 1
- Static methods doesen't work HOT 3
- ShimHelper.ValidateReplacementMethodSignature has ambiguous and vague output that does not help with debugging
- Stack Overflow when trying to use shim from task HOT 1
- Is this library Dead? HOT 1
- Mono Dependencies out of date.
- Issue with NET7 HOT 2
- :star: ANNOUNCEMENT: VERSION 2.0 RELEASED TO NUGET :star: HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pose.