Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unit testing #65

Closed
xp-development opened this issue Jun 30, 2015 · 12 comments
Closed

Unit testing #65

xp-development opened this issue Jun 30, 2015 · 12 comments

Comments

@xp-development
Copy link
Contributor

Currently, it is hard to write unit tests. E.g. I need to write a lot of mock classes to verify if a region shows the expected view. The StockTraderRI sample shows a mock class for the region manager:
https://compositewpf.codeplex.com/SourceControl/latest#V5/StockTrader RI/Desktop/StockTraderRI.Modules.Position.Tests/Mocks/MockRegionManager.cs

Is it possible to provide a prism unit test package for easier testing?

@brianlagunas
Copy link
Member

This will be a very low priority. Since there are mock classes available in Prism's unit tests as well as the old Stock Trader app, this isn't going to be something I get to anytime soon. This is where a pull request would come in handy :0)

@bartlannoeye
Copy link
Contributor

Would you like to see a package providing a test dll with mocks for most of the Prism classes, or rather a package bringing in some mocked code files so you can still tweak the mocks afterwards?

In both cases Prism will push a mocking framework into your test project while you might be choosing to use another. Adding support for multiple frameworks is an option, but I'd rather see that effort go into Prism itself rather than somewhat facilitating testing (like Brian said, the code is already there for grabs).

@xp-development
Copy link
Contributor Author

I can't understand why this has a low priority. If I search a framework for my next project, one of my choosing criteria is testability. If I develop a big business application, it is necessary to test.

@bartlannoeye: The region manager is very complex with a deep object hierarchy. (RegionManager->RegionCollection->Region->ViewsCollection). So, I don't know if it clever to use a mocking framework. Maybe it is clever to write own mock classes like the StockTraderRI sample.
I thought of a package providing a test dll. But a package bringing mocked code files is a good idea, too.

@briannoyes
Copy link
Contributor

@jan-schubert I'm not sure I understand exactly what you are looking for. Prism has nearly 100% code coverage of the framework code. And a little history - when we first developed Prism 1.0 (aka Composite Application Guidance for WPF), we were not allowed to use a proper mocking framework because of constraints Microsoft legal put on us so we had to write manual mock classes for everything. Later in Prism 4 we got past that and could use MOQ and did. But the mock classes you see in the Stock Trader are remnants from Prism 1 - us doing something we didn't want to have to do in the first place.

If you have a clear idea for what kind of unit test helpers or mock helpers you need, then I would encourage you to implement them and submit as a pull request.

@xp-development
Copy link
Contributor Author

I know prism has a high code coverage. That's great! In the current prism 6 solution there are four test classes named MockRegionManager which inherits from IRegionManager. I think it's possible to test with Moq instead of writing a own MockRegionManager class, but it is very hard to use Moq for this cases.
E.g.: I want to write a small and simple test. My class under test gets a IRegionManager and if I call the method Foo of my class, the region manager calls the RequestNavigate method with some parameters. My unit test should verify if the region manager was called with the correct params.

public class ClassUnderTest
{
    public ClassUnderTest(IRegionManager regionManager)
    {
        _regionManager = regionManager;
    }

    public void Foo()
    {
        _regionManager.RequestNavigate("MainRegion", new Uri(typeof(MyView).FullName, UriKind.Relative));
    }

    private readonly IRegionManager _regionManager;
}

Perhaps there is an easy way to test this with Moq, but I think mock helper classes are a better variant.

@briannoyes
Copy link
Contributor

Any method invocation on an interface dependency is trivial to mock out with MOQ, especially with fairly static parameters like those, but even when the parameters vary per call. If you are not familiar with how to do that, I'd strongly suggest looking into it. It is liberating to be able to handle these kinds of scenarios with a single line of mocking code to setup expectations instead of having to code a whole class that you can parameterize.

@sgrassie
Copy link

sgrassie commented Jul 2, 2015

As @briannoyes said using Moq to test this is fairly trivial, as this (un-tested) code shows:

[Test]
public void Foo_Should_CallRequestNavigate()
{
    var mockRm = new Mock<IRegionManager>();
    mockRm.Setup(x => x.RequestNavigate("MainRegion", new Uri(typeof(MyView).FullName, UriKind.Relative).Verifiable();
    var sut = new ClassUnderTest(mockRm.Object);

    sut.Foo();

    mockRm.VerifyAll(); 
}

The last line of the test basically instructs Moq to assert that the RequestNavigate method was indeed called with those parameters.
In a real test class, you would probably want to re-create the mock IRegionManager in the test setup method, and .Setup particular methods on a per-test basis.

@xp-development
Copy link
Contributor Author

@briannoyes: You are right. It is better to handle these scenarios with a single line of mocking code to setup expectations instead of having to code a whole class that can be parameterized.

@sgrassie: I know Moq, but it is not so trivial to mock this, because the method RequestNavigate is an extension method and Moq cannot mock static classes or static methods.

To verify this simple test with Moq you need some mock classes. One for the region manager to get the mocked regions collection. One fake for region collection that received the region. And one mock for the region itself. So I think its better to use mock helper classes.

@xp-development
Copy link
Contributor Author

Why use prism extension methods to extend some classes? If the classes / interfaces will be extended directly, testing will be much easier, like @sgrassie shows in his last post.

@briannoyes
Copy link
Contributor

Closing as core issue is same as #43 - consider moving extension methods onto interfaces to make them easier to test. We will not be pursuing adding mock classes since we consider using a mocking library a more maintainable approach.

@bartlannoeye
Copy link
Contributor

Do you have the latest pre-release version? These methods used to be non-async (thus void) in before December. Maybe that's why you don't see it.

Sent from my Windows Phone

@lock
Copy link

lock bot commented Jan 31, 2020

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Jan 31, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants