jediwhale / fitsharp

Functional testing tools for .NET
http://fitsharp.github.io
Other
152 stars 73 forks source link

Support for extension methods #152

Closed matthewseng closed 2 years ago

matthewseng commented 6 years ago

Hi @jediwhale,

First of all thanks for the nice work on this.

Is it possible to support extension methods? Right now, we are getting MissingMethodException when we use extension methods in our fixtures. System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> fitSharp.Machine.Exception.CreateException: Constructor with 0 parameter(s) failed for type 'XXX.XXX.Fixture.QueueFixture'. ---> System.MissingMethodException: Method not found: 'Microsoft.Extensions.Configuration.IConfigurationBuilder ...

Thanks again.

jediwhale commented 6 years ago

I'll look into this.

jediwhale commented 6 years ago

What does your fixture code and the test that uses it look like?

ferminquant commented 2 years ago

Hello, has any progress been made on supporting extension methods?

I am running into the same (or at least very similar) problem. I have a class with an extension method (in another class but in the same namespace and assembly), a test that uses that extension method, and an error when I run the test saying the method does not exist. But it does exist, and the whole project compiles and runs without issues, but the test fails.

I looked a bit into it, and it seems to be that in fitSharp.Machine.Engine.MemberQuery.FindMatchingMember, it calls System.Type.GetMembers to verify whether the method being called exists or not, and since it is an extension method, of course reflection does not find it as being part of the Type in question (since extension methods don't actually modify the type, it is just syntactic sugar), so the matcher in fitSharp.Machine.Engine.BasicMemberMatcher.Match does not find the method, returns "Maybe.Nothing" up the call stack and eventually throws the error at fitSharp.Slim.Operators.InvokeInstructionBase.InvokeMember by using fitSharp.Machine.Model.TypedValue.ThrowExceptionIfNotValid

Thanks

jediwhale commented 2 years ago

What does the test look like?

jediwhale commented 2 years ago

As expected, extension methods are not found, as they are in a different class. To test this I added an extension method: public static class SampleExtension { public static int Increase(this SampleClass sample, int increment) { return sample.CountBy(increment); } } Here is a workaround, by executing the method in the extension class passing the original object as the first parameter: TryExtension

This is a little messy - I'm going to make a cleaner way to do this.

ferminquant commented 2 years ago

Thanks for looking into this, and for the workaround. I am trying to test your workaround, please let me know if I understood you correctly. Instead of calling sampleClass.Increase(2); the workaround is to call SampleExtension.Increase(sampleClass,2);, is this correct?

If so, would you please help me know how to call a static method from a fitsharp test, this is what I currently have, but it fails with Method getidextension not found in ExtensionMethodsTestLibrary.TestClass

My test:

!|import|
|ExtensionMethodsTestLibrary|

!|script    |TestClass  |
|$variable2=|GetID      |
|$obj=      |Get Fixture|

!|script    |TestClassExtensions|
|$variable1=|GetIDExtension     |$obj|

My class:

public class TestClass
{
    public string Name;
    public TestClass() { Name = "Test"; }
    public int GetID() { return 1; }
}

public static class TestClassExtensions
{
    public static int GetIDExtension(this TestClass testClass) { return 2; }
}
jediwhale commented 2 years ago

Thanks for the example. I was looking at Fit tests, I see you're using Slim tests. I'll investigate if there's a way to do it with Slim tests.

jediwhale commented 2 years ago

See release 2.8.3 in nuget. Uses the syntax methodName .in. extensionclass

Slim example: image