MvvmCross: Unit-testing services with plugins

2019-07-15 14:06发布


I am creating a cross-platform project with MvvmCross v3 and Xamarin solution and i would like to create some unit-tests. This seems a bit outdated, so i was trying to follow this and it worked as expected.

However, I am now making an attempt to unit-test some of my domain services, which are dependent on platform specific MvvvCross plugins (e.g ResourceLoader).

Running the test results in the following exception:

Cirrious.CrossCore.Exceptions.MvxException: Failed to resolve type   
Cirrious.CrossCore.Plugins.IMvxPluginManager.

I assume that IMvxPluginManager is probably registered in the Setup flow, and that I need to include platform implementation of the plugins in my project, yet I was wondering what would be the preferred way of setting up my unit-test project? Is there something that I am missing?

Is there any updated tutorial for the above task?

Are there already any plugin platform extensions that supports test environment, or should I make an attempt to write them by myself?

2条回答
forever°为你锁心
2楼-- · 2019-07-15 14:35

This scenario should be well possible. I wanted to UnitTest my SqlLite service implementation. I did the following to get it to work:

  • Create a Visual Studio unit test project
  • Add a reference to .Core portable library project
  • Add a nuget reference To MvvmCross Test Helper
  • Add a nugget reference to MvvmCross SqlLite Plugin ( this will make use of the WPF implementation of SqlLite)

Download the SqlLite windows library and copy these into your test project Sql Lite Download location And make sure to add the sqllite3.dll to the root of your unit test project and set the "Copy to Output Library" to "Copy always". This will make sure the actual sqllite database is copied to the unit test dll location. (Check that the DLL is copied to your bin/debug folder)

Then write you unit test the following way:

[TestClass]
public class SqlServiceTests:MvxIoCSupportingTest
{
    private readonly ISQLiteConnectionFactory _factory;

    public SqlServiceTests()
    {
        base.ClearAll();

        _factory = new MvxWpfSqLiteConnectionFactory();
        Ioc.RegisterSingleton<ISQLiteConnectionFactory>(_factory);
    }
    [TestMethod]
    public void YourSqlLiteTest()
    {
        // Arrange
        var si = new SqlDataService(_factory);
        var list = si.GetOrderList();
    }
}

I haven't tested this with my viewmodel. By using the IoC.RegisterSingleton method the SqlConnectionFactory should be readyli available for your viewmodels.

查看更多
Juvenile、少年°
3楼-- · 2019-07-15 14:39

In general, you shouldn't be loading the plugins or a real MvxPluginManager during your service tests.

Instead your unit tests should be registering mock types for the interfaces that your services need to use.

var mock = new Mock<INeedToUse>();
// use mock.Setup methods
Ioc.RegisterSingleton<INeedToUse>(mock.Object);
// or you can use constructor dependency injection on INeedToUse instead

You can also register a mock IMvxPluginManager if you really need to, but in the majority of cases I don't believe you should need that. If you've got a case where you absolutely need it, please post a code sample - it's easier to talk in code than text.

查看更多
登录 后发表回答