[Prism] 019. Prism의 테스트 가능성, 뷰모델 테스트 구현하기

WPF(Windows Presentation Foundation)는 데스크탑 응용 프로그램을 개발하기 위한 강력한 기술로, 사용자 인터페이스(UI)와 비즈니스 로직을 분리하여 코드의 재사용성과 유지보수성을 높입니다. Prism은 WPF 애플리케이션의 구조와 패턴을 개선하는 데 중점을 두고 있는 프레임워크이며, MVVM(Model-View-ViewModel) 아키텍처를 채택하여 애플리케이션의 테스트 가능성을 극대화합니다. 본 글에서는 Prism 프레임워크에서 뷰모델을 어떻게 테스트할 수 있는지에 대해 자세히 다뤄보겠습니다.

Prism 프레임워크와 MVVM 패턴

Prism은 여러 핵심 패턴과 원칙을 제공하여 WPF 애플리케이션의 구조를 정리합니다. MVVM 패턴은 이러한 패턴 중 하나로, UI와 비즈니스 로직을 효과적으로 분리하여 각각의 독립적인 테스트를 가능하게 합니다. MVVM에서 ViewModel은 View와 Model 사이에서 데이터 바인딩을 담당하며, UI와 비즈니스 로직 사이의 상호작용을 관리합니다.

테스트 가능성의 중요성

신뢰성 높은 소프트웨어를 개발하기 위해서는 단위 테스트가 필수적입니다. Prism을 사용하면 뷰모델을 독립적으로 테스트할 수 있기 때문에, UI와의 상호작용을 신경 쓰지 않고도 비즈니스 로직을 검증할 수 있습니다. 이는 코드의 품질을 높이고, 유지 보수 비용을 줄이며, 개발 주기를 단축하는 데 기여합니다.

뷰모델 테스트 구현하기

이제 Prism을 사용하여 뷰모델을 어떻게 테스트하는지에 대해 구체적인 예제를 통해 알아보겠습니다. 다음은 간단한 Todo List 애플리케이션의 뷰모델을 테스트하는 방법입니다.

1. TodoItem 클래스 정의


public class TodoItem
{
    public string Title { get; set; }
    public bool IsCompleted { get; set; }
}
    

2. TodoViewModel 클래스 정의


using Prism.Commands;
using Prism.Mvvm;
using System.Collections.ObjectModel;

public class TodoViewModel : BindableBase
{
    private string _newTodoTitle;
    public string NewTodoTitle
    {
        get { return _newTodoTitle; }
        set { SetProperty(ref _newTodoTitle, value); }
    }

    public ObservableCollection TodoItems { get; private set; }
    public DelegateCommand AddTodoCommand { get; private set; }

    public TodoViewModel()
    {
        TodoItems = new ObservableCollection();
        AddTodoCommand = new DelegateCommand(AddTodo, CanAddTodo).ObservesProperty(() => NewTodoTitle);
    }

    private void AddTodo()
    {
        if (!string.IsNullOrWhiteSpace(NewTodoTitle))
        {
            TodoItems.Add(new TodoItem { Title = NewTodoTitle });
            NewTodoTitle = string.Empty;
        }
    }

    private bool CanAddTodo()
    {
        return !string.IsNullOrWhiteSpace(NewTodoTitle);
    }
}
    

3. 뷰모델 테스트 구현

이제 커뮤니티에서 널리 사용되는 NUnit과 Moq를 사용하여 위에서 정의한 TodoViewModel 클래스를 테스트해보겠습니다.


using NUnit.Framework;
using Prism.Commands;
using System.Collections.ObjectModel;

[TestFixture]
public class TodoViewModelTests
{
    private TodoViewModel _viewModel;

    [SetUp]
    public void SetUp()
    {
        _viewModel = new TodoViewModel();
    }

    [Test]
    public void AddTodo_ShouldAddTodoItem()
    {
        // Arrange
        _viewModel.NewTodoTitle = "Test Todo";

        // Act
        _viewModel.AddTodoCommand.Execute();

        // Assert
        Assert.AreEqual(1, _viewModel.TodoItems.Count);
        Assert.AreEqual("Test Todo", _viewModel.TodoItems[0].Title);
    }

    [Test]
    public void AddTodo_WhenTitleIsEmpty_ShouldNotAddTodoItem()
    {
        // Arrange
        _viewModel.NewTodoTitle = string.Empty;

        // Act
        _viewModel.AddTodoCommand.Execute();

        // Assert
        Assert.AreEqual(0, _viewModel.TodoItems.Count);
    }

    [Test]
    public void CanAddTodo_WhenTitleIsNotEmpty_ShouldReturnTrue()
    {
        // Arrange
        _viewModel.NewTodoTitle = "Test Todo";

        // Act
        var canAdd = _viewModel.AddTodoCommand.CanExecute();

        // Assert
        Assert.IsTrue(canAdd);
    }

    [Test]
    public void CanAddTodo_WhenTitleIsEmpty_ShouldReturnFalse()
    {
        // Arrange
        _viewModel.NewTodoTitle = string.Empty;

        // Act
        var canAdd = _viewModel.AddTodoCommand.CanExecute();

        // Assert
        Assert.IsFalse(canAdd);
    }
}
    

테스트 실행 및 결과 확인

작성한 테스트 코드를 실행하고 결과를 확인합니다. NUnit에서는 Visual Studio에서 통합된 테스트 기능을 제공하므로 테스트 탐색기를 통해 결과를 쉽게 확인할 수 있습니다. 모든 테스트가 성공하면 뷰모델이 정확하게 동작하고 있음을 의미합니다.

정리

Prism 프레임워크를 사용하면 WPF 애플리케이션의 뷰모델을 효율적으로 테스트할 수 있습니다. MVVM 패턴을 통해 UI와 비즈니스 로직을 분리하고, 다양한 단위 테스트를 통해 코드의 신뢰성을 높일 수 있습니다. 이로 인해 안정적이고 유지 보수가 용이한 애플리케이션을 구축하는 데 큰 도움을 받을 수 있습니다.