0
votes

Update:

Added requested table drawing code, where the MessageBoxService.Show() called.

/// <summary>
    /// Draws the classic sudoku table with the given size.
    /// </summary>
    protected override void Draw(object o)
    {
        if (GetCurrentTableViewModel() != null && GetCurrentTableViewModel().AreAnyCellsFilled())
        {
            var messageBoxResult = MessageBoxService.Show(
               Resources.MessageBox_DrawIfNumbersArePresented,
               Resources.MessageBox_Question_Title, MessageBoxButton.YesNo, MessageBoxImage.Question);

            if (messageBoxResult == MessageBoxResult.No || messageBoxResult == MessageBoxResult.Cancel)
            {
                return;
            }
        }

        SudokuBoardSize sudokuBoardSize = (SudokuBoardSize)o;

        bool oldDiagonalRulesStatus = AreDiagonalRulesApplied;
        if (sudokuBoardSize.Height == 9 && sudokuBoardSize.Width == 9)
        {
            SudokuBoardControl = new UcClassicSudoku9x9Table();
            _actualSudokuBoard = CreateBoard(sudokuBoardSize, (BaseSudokuTableViewModel)SudokuBoardControl.DataContext, false);
        }
        else if (sudokuBoardSize.Height == 6 && sudokuBoardSize.Width == 6)
        {
            SudokuBoardControl = new UcClassicSudoku6x6Table();
            _actualSudokuBoard = CreateBoard(sudokuBoardSize, (BaseSudokuTableViewModel)SudokuBoardControl.DataContext, false);
        }
        else
        {
            SudokuBoardControl = new UcClassicSudoku4x4Table();
            _actualSudokuBoard = CreateBoard(sudokuBoardSize, (BaseSudokuTableViewModel)SudokuBoardControl.DataContext, false);
        }

        ((BaseClassicSudokuTableViewModel)SudokuBoardControl.DataContext).AreDiagonalRulesApplied = oldDiagonalRulesStatus;
        SolutionCounter = string.Empty;
        IsSolutionCounterVisible = false;
        _solutions.Clear();
    }

I am new on Stackoverflow, so sorry for any mistakes.

I am developed a Sudoku solver hobby project and I would like to add Unit tests to it. It is fully MVVM. (https://github.com/denesdavid/Solvedoku)

I wanted to test 'the drawing of a new empty table' feature when there is at least one filled cell in the current Sudoku. The software asks you in this case if you really want to draw a new one. I would like to bypass this question, I mean...simulating to press on the Yes button. I read that Moq is perfect for this, but it is not working for me currently. The question pops up during unit testing, but I have to click on Yes manually.

Here is my test:

[TestMethod]
    public void Draw9x9TableWithAlreadyFilledCellsTest()
    {
        Mock<IMessageBoxService> messageBoxMock = new Mock<IMessageBoxService>(MockBehavior.Strict);
        messageBoxMock.Setup(m =>
            m.Show(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<MessageBoxButton>(),
            It.IsAny<MessageBoxImage>()));
        messageBoxMock.SetReturnsDefault(MessageBoxResult.OK);
        
        ClassicSudokuViewModel classicSudokuViewModel = new ClassicSudokuViewModel(messageBoxMock.Object);
        SudokuBoardSize sudokuBoardSize = new SudokuBoardSize();
        sudokuBoardSize.Height = 9;
        sudokuBoardSize.Width = 9;
        sudokuBoardSize.BoxCountX = 3;
        sudokuBoardSize.BoxCountY = 3;

        
        BaseSudokuTableViewModel tableViewModel = classicSudokuViewModel.GetCurrentTableViewModel();
        tableViewModel.Cells[0][0] = "1";
        classicSudokuViewModel.DrawSudokuCommand.Execute(sudokuBoardSize);
        object actualBoard = classicSudokuViewModel.SudokuBoardControl;
        tableViewModel = classicSudokuViewModel.GetCurrentTableViewModel();

        Assert.AreEqual(typeof(UcClassicSudoku9x9Table), actualBoard.GetType());
        Assert.AreEqual(string.Empty, tableViewModel.Cells[0][0]);
        Assert.AreEqual(false, classicSudokuViewModel.AreDiagonalRulesApplied);
        Assert.AreEqual(string.Empty, classicSudokuViewModel.SolutionCounter);
        Assert.AreEqual(false, classicSudokuViewModel.IsSolutionCounterVisible);
        Assert.AreEqual(0, classicSudokuViewModel.Solutions.Count);
    }

IMessageBoxService:

public interface IMessageBoxService
{
    /// <summary>
    /// Shows a MessageBox with the given text, title, button(s) and image.
    /// </summary>
    /// <param name="messageText">Text of the MessageBox.</param>
    /// <param name="title">Title of the MessageBox</param>
    /// <param name="messageBoxButton">Button(s) of the MessageBox</param>
    /// <param name="messageBoxImage">Image of the MessageBox</param>
    /// <returns>MessageBoxResult</returns>
    MessageBoxResult Show(string messageText, string title, MessageBoxButton messageBoxButton,
        MessageBoxImage messageBoxImage);

    /// <summary>
    /// Shows a MessageBox with the given text, title, button(s), image and style.
    /// </summary>
    /// <param name="messageText">Text of the MessageBox.</param>
    /// <param name="title">Title of the MessageBox</param>
    /// <param name="messageBoxButton">Button(s) of the MessageBox</param>
    /// <param name="messageBoxImage">Image of the MessageBox</param>
    /// <param name="messageBoxStyle">Style of the MessageBox</param>
    /// <returns>MessageBoxResult</returns>
    MessageBoxResult Show(string messageText, string title, MessageBoxButton messageBoxButton,
        MessageBoxImage messageBoxImage, Style messageBoxStyle);
}

}

MessageBoxService:

class MessageBoxService : DependencyObject, IMessageBoxService
{
    private Style _messageBoxStyle = (Style)Application.Current?.Resources["MessageBoxStyle"];

    /// <summary>
    /// Displays a messagebox with the given parameters.
    /// </summary>
    /// <param name="messageText">Text of the messagebox.</param>
    /// <param name="title">Title of the messagebox.</param>
    /// <param name="messageBoxButton">Displayed button(s) in the messagebox. (Choose from the MessageBoxButton enum.).</param>
    /// <param name="messageBoxImage">Displayed icon in the messagebox. (Choose from the MessageBoxImage enum.).</param>
    /// <returns>MessageBoxResult</returns>
    public MessageBoxResult Show(string messageText, string title, MessageBoxButton messageBoxButton, MessageBoxImage messageBoxImage)
    {
        return Xceed.Wpf.Toolkit.MessageBox.Show(Application.Current?.MainWindow, messageText, title, messageBoxButton, messageBoxImage, _messageBoxStyle);
    }

    /// <summary>
    /// Displays a messagebox with the given parameters.
    /// </summary>
    /// <param name="messageText">Text of the messagebox.</param>
    /// <param name="title">Title of the messagebox.</param>
    /// <param name="messageBoxButton">Displayed button(s) in the messagebox. (Choose from the MessageBoxButton enum.).</param>
    /// <param name="messageBoxImage">Displayed icon in the messagebox. (Choose from the MessageBoxImage enum.).</param>
    /// <param name="messageBoxStyle">Style what is applied on the MessageBox.</param>
    /// <returns>MessageBoxResult</returns>
    public MessageBoxResult Show(string messageText, string title, MessageBoxButton messageBoxButton, MessageBoxImage messageBoxImage, Style messageBoxStyle)
    {
        return Xceed.Wpf.Toolkit.MessageBox.Show(Application.Current?.MainWindow, messageText, title, messageBoxButton, messageBoxImage, messageBoxStyle);
    }
}

}

Thank you for your help!

1
The Interface has two methods, be sure to mock the correct one.Max
Can you show ClassicSudokuViewModel? In particular the part where is called Show.vernou
@vernou I added it to the post.DariusDavedane
Can you debug the test and check the property MessageBoxService is the mock?vernou
The mock seems to be correct. I also created a completely independent project and solution and the messagebox mocking works there like a charm. I really don't understand what is happening here.DariusDavedane

1 Answers

0
votes

The problem is solved.

Thank you @vernou for your time and help. The problem was in the BaseSudokuTableViewModel class, it is called the ViewModelBase class with a completely new MessageBoxService instance, so not with the mocked one, so this overrided the mock.

I know this was a banal mistake, but I am being tired nowadays beause of my job.

Thank you very much again!