dotnet / maui

.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.
https://dot.net/maui
MIT License
21.96k stars 1.7k forks source link

Unit test projects can't reference Maui multi target projects #3552

Closed JohnHDev closed 1 year ago

JohnHDev commented 2 years ago

Description

With the new design for multi target projects, we need to be able to unit test ViewModels stored in Maui projects.

We could move ViewModels into pure .net 6 projects, but dependencies that are defined in other multi target projects with platform specific implementations can't be mocked regardless without also moving the interfaces for those dependencies into .net 6 projects. That largely negates the positives of multi target projects if we have to create other projects just to contain the Interface definitions and view models.

Steps to Reproduce

Create a .NET Maui solution Create a ViewModel to the .NET Maui project. Create a unit test project and add a reference to the .NET Maui project.

Version with bug

Preview 10 (current)

Last version that worked well

Unknown/Other

Affected platforms

I was not able test on other platforms

Affected platform versions

All

Did you find any workaround?

Create another .net 6 project for view modals and interfaces that the tests and .net maui projects can reference. That just doesn't scale well.

Relevant log output

No response

ismasanchez commented 1 year ago

In my opinion, there should be at least two options, number 2 that you mentioned is adequate, but is not enough, a MAUI project should be able to be referenced by libraries requiring .net6 without any workaround. The .csproj files should not be edited manually, my proposal would be that whenever a new MAUI project is launch, a dialog screen is shown where you choose which platforms do you want to develop (with checkboxes), if you choose only Android, only android and .net6 target frameworks are included, and both the compiler and VS should disregard .net6, so it doesn't bother you with any type of error or warning even if you implement platform specific code around the project.

codingL3gend commented 1 year ago

my solution to this issue only required 1 #if condition in the shared platform specific code and very minimal change to the csproj. i do agree that it shouldnt be required to have to make such changes but as i mentioned before

"i did recently see with a new .net maui application that the Unit Testing project doesnt have the true and it built and ran test without an issue, even referencing ViewModels. so there could be some potential there"

balintn22 commented 1 year ago

I just had the same problem. My app may be bigger, so I already had my domain logic separated out. I wanted to test my ViewModels as well The problem was I had VMs next to pages, to make finding corresponding pieces easier. Not being able to unit test VMs when they are part of the Maui app, I said, what the heck, time to separae them out. So I created MyApp.ViewModels net6 library, referenced from MyApp Maui executable project and mirrored the folder hierarchy - again, to be able to find things that are now pushed quite far from each other (VMs and Views). Tradeoff, acceptable. Then came the problem of Commands, you know the new way of handling button taps. AND they should be placed in your VMs to bind the UI to. Trouble is, they are declared in Microsoft.Maui.Controls - a UI reference :-( So the way to resolve this would be to get rid of the new shiny Commands and go back to event handlers (which are implemented in View code-behind). Again, possible, but annoying. In fact, the logic in VM tap handlers is cleaner now (without any UI responsibility), but had to put some logic into the View code-behind (thus on the UI). And then I got stuck. I have some logic in my VM that determines the color of some UI elements via binding their color to a VM property. It used to be a color hex string, but that stopped working when I migrated my app from Xamarin to Maui. And binding BackgroundColor didn't work either. The workaround was to bind the UI elements' Background porperty (a Brush) rather than their BackgroundColor. And I couldn't be bothered to spend more time on finding a workaround for this workaround, I'm giving up on splitting out and unittesting my VMs'.

mattleibow commented 1 year ago

This should now be fixed with .NET 8 preview 2. Let me test and confirm...

mattleibow commented 1 year ago

image