pixel
pixel

Reputation: 10577

Xamarin Forms Unit Testing a Command

I am trying to unit test a Command in Xamarin.Forms.

I have my view-model class as an example like this

public class CarViewModel
{
    public Command SelectedCommand { get; } => new Command(OnSelected);

    public Car SelectedCar
    {
      get { return _selectedCar; }
      private set { _selectedCar = value; }
    }

    private void OnSelected(object obj)
    {
      if (obj is Car car) 
      {
        SelectedCar = car;
      }
    }
}

This class is the BindingContext for my view and the SelectedCommand above is fired when user taps on a ListView item, so it is a method that is bound to a Command in XAML using a TapGestureRecognizer like

<TapGestureRecognizer Command="{Binding SelectedCommand}" .../>

I am trying to unit test this class, so my CarViewModel class is subject under test (SUT) inside my test.

I just started looking at mocking libraries / isolation frameworks and I see Moq is quite popular.

My questions are:

  1. Since I dont have any dependencies in my CarViewModel below, I dont think I need to mock that class in my test. It is subject under test which to my understanding should not be mocked. Only dependencies should be mocked. Is this correct?
  2. How do I unit test to confirm that my SelectedCommand has been called and that it has set SelectedCar property? If I am right in 1 above, then Moq is not even needed to test this since I have no dependency to mock for my CarViewModel class.

Upvotes: 1

Views: 1747

Answers (1)

Nkosi
Nkosi

Reputation: 247163

Based on the current code in the example provided there really is no need to mock anything.

Execute the command on the SUT with a known parameter and verify the expected behavior via the SelectedCar.

[Test]
public void SelectedCommand_Should_Set_SelectedCar {
    // Arrange
    var expected = new Car();
    var subject = new CarViewModel();

    // Act
    subject.SelectedCommand.Execute(expected);

    // Assert    
    var actual = subject.SelectedCar;    
    Assert.AreEqual(expected, actual);
}

Upvotes: 2

Related Questions