stryker-net icon indicating copy to clipboard operation
stryker-net copied to clipboard

Support for blazor

Open Terebi42 opened this issue 3 years ago • 7 comments

Describe the bug Doesnt work at all.

Logs attached

Expected behavior It Works

Desktop (please complete the following information):

  • OS: Win10
  • Type of project Core Blazor
  • Framework Version 3.1
  • Stryker Version latest

Additional context Very first try. Using Blazor empty template pretty much

VsTest-log.host.21-03-23_15-21-50_54782_9.txt VsTest-log.host.21-03-23_15-21-52_23693_9.txt VsTest-log.txt log-20210323.txt

Terebi42 avatar Mar 23 '21 20:03 Terebi42

We have never tried Stryker on blazor, we'll need to figure out what's happening here and build support for it. Thank you for letting us know blazor does not work out of the box!

rouke-broersma avatar Mar 23 '21 20:03 rouke-broersma

I'm getting this issue too. Compilation errors occur on methods like StateHasChanged, OnInitializedAsync, OnAfterRenderAsync and other Blazor-specific methods.

I believe this might be caused by the fact that I am using a partial class: One Page.razor with a Page.razor.cs Even in Visual Studio, the Page.razor.cs is sometimes not recognized as being a Blazor class.

When I have time, I can try testing my theory, by simply making one razor.cs without a partial class and on with the partial class

InzeNL avatar Oct 27 '21 12:10 InzeNL

Seems that the partial class is indeed the cause of this problem. I create two test projects that can be found here: https://github.com/InzeNL/stryker-net-blazor-test

Running dotnet stryker for InzeNL.Stryker.Blazor.NoPartialClasses will result in a successful run of the Stryker mutator

Running dotnet stryker for InzeNL.Stryker.Blazor will result in the Stryker mutator failing

To be more specific, I do not think the issue is in the partial class of Page.razor.cs, but instead, Page.razor is not recognized as the other part of the partial class by the compiler.

InzeNL avatar Oct 27 '21 13:10 InzeNL

Thanks for your analysis. This confirms that Stryker is not able to support Razor projects without significant effort. As of now, Stryker must directly handle project build tasks as we cannot use MsBuild for that. Razor depends on specific MsBuild tasks that are not implemented in Stryker; Stryker only perform compilation steps and a decent ressource build phase. Anything else (such as .razor files processing) is not supported.

dupdob avatar Oct 27 '21 13:10 dupdob

Thanks for your analysis. This confirms that Stryker is not able to support Razor projects without significant effort. As of now, Stryker must directly handle project build tasks as we cannot use MsBuild for that. Razor depends on specific MsBuild tasks that are not implemented in Stryker; Stryker only perform compilation steps and a decent ressource build phase. Anything else (such as .razor files processing) is not supported.

Coming here to confirm that it would be great if y'all could invest the effort to supporting this, though I understand the difficulty in doing so.

Christian-Oleson avatar Apr 22 '22 15:04 Christian-Oleson

I believe we have an intern working on this as their internship project right now.

rouke-broersma avatar Apr 22 '22 15:04 rouke-broersma

I just had the same problem. As a workaround, one can add the ComponentBase in the partial class, even though it would normally be omitted. The compiler is still fine, and Stryker worked that way.

// public partial class MyComponent
public partial class MyComponent : ComponentBase
{ }

Also, eventually related to this issue:

If you have injected services defined in razor, but they are used in the partial class (happened when I refactored to partial class), the compiler is fine, but Stryker will fail to compile mutated projects.

You will get warnings and errors like:

An object reference is required for the non-static field, method, or property 'MyService.Property'
...
Stryker.NET could not compile the project after mutation.

To fix it, I removed the service from the markup

@inject IService MyService

and instead, defined it in the partial class

[Inject]
IService MyService { get; set; } = null!;

After that, everything worked for me.

kaipm avatar Jun 05 '22 15:06 kaipm