2
votes

Comment tester unitaire cette méthode c # qui utilise la console?

Comment tester cette méthode dans le code? Dois-je simplement mettre une valeur dans les entrées que j'ai ou autre chose? Il devrait tester le fonctionnement d'ISD en vérifiant en créant correctement une chanson avec les détails corrects

static Song InputSongDetails()
{
    Console.WriteLine("What is the name of your song");
    string name = Console.ReadLine();

    Console.WriteLine("What is the artists name");
    string artist = Console.ReadLine();

    int records;
    Console.WriteLine("How many records did it sell");
    while (!int.TryParse(Console.ReadLine(), out records) || records < 0)
    {
        Console.WriteLine("That is not valid please enter a number");
    }
    return new Song(name, artist, records);
}


12 commentaires

Copie possible du test unitaire C # pour une méthode qui appelle Console.ReadLine ()


Voulez-vous écrire des tests unitaires automatisés? Si tel est le cas, Console.ReadLine devra être modifié.


Vous pouvez écrire un test (unitaire) automatisé en remplaçant Console.In et Consiole.Out. Mais la meilleure approche consiste à refactoriser en une partie d'entrée et une partie de validation / traitement.


Une erreur qui est souvent faite est de penser à "comment se moquer / stub / ..." avant de définir "quoi tester". Veuillez décrire ce que votre test devrait réellement faire? Voulez-vous tester si quelque chose a été écrit sur la console? Ou quelles sont les valeurs de propriété de la chanson renvoyée? Ou quelque chose de différent? Il n'y a pas de "test" pour une méthode, tout comme il n'y a pas de "méthode". Lorsque vous souhaitez tester une méthode, vous voulez qu'elle se comporte de manière attendue dans certaines conditions. Cependant, vous n'avez pas fourni ces conditions ni comment vous vous attendez à ce que votre méthode se comporte.


@HimBromBeere Il suffit de tester que la méthode fonctionne correctement en créant une chanson avec les détails corrects


Et qu'est-ce que «correctement»? Vous semblez avoir des conditions qui indiquent ce que cela signifie, par exemple lorsque l'utilisateur a tapé "Hans", l'auteur de la chanson devrait également être "Hans".


@HimBromBeere La seule condition est que les enregistrements ne peuvent pas être une chaîne ou une valeur négative


Ensuite, je suppose que vous avez trois tests, pas un seul. Un pour une chaîne, un pour un nombre négatif et un "habituel".


@ Umarfarooq99 savez-vous comment mettre un point d'arrêt? Je veux dire que c'est ce que nous faisons habituellement avant d'aller dans la dure, votre méthode est simple.


Je suis d'accord avec M.kazem, ne testez pas quelque chose d'unité qui ne soit pas testable en soi pour le plaisir d'écrire des tests. Votre membre semble assez simple, il suffit de le parcourir et de voir ce qui se passe.


@ M.kazemAkhgary Oui, je sais comment mettre un point d'arrêt mais pour le moment je dois faire une démonstration de tests unitaires


@HimBromBeere Oui, je sais comment mettre un point d'arrêt mais pour le moment je dois faire une démonstration de tests unitaires


3 Réponses :


3
votes

La meilleure approche serait probablement d'abstraire la Console en utilisant une interface. Mais vous pouvez également pré-remplir le tampon In de la Console avec les données souhaitées.

Par exemple:

var data = String.Join(Environment.NewLine, new[]
{
    "Let it be",
    "Beatles",
    // ...
});

Console.SetIn(new System.IO.StringReader(data));

// usage:
var songName = Console.ReadLine();
var artistName = Console.ReadLine();


2 commentaires

cela ne deviendrait-il pas difficile si Console.ReadLines est conditionnel? semble bien pour le cas OP


@ M.kazemAkhgary, je suis d'accord. Mais cela conviendrait généralement aux cas de base et peut vous faire gagner du temps lors des tests unitaires.



0
votes

Il y a deux façons de tester l'entrée et / ou la méthode.

après chaque entrée, imprimer le résultat Console.WriteLine (MyVar)

static Song InputSongDetails(string name,string artist, int records)
    {
        return new Song(name, artist, records);
    }

Vous pouvez également séparez la méthode pour saisir le paramètre que vous avez déjà validé.

static Song InputSongDetails()
{
    Console.WriteLine("What is the name of your song");
    string name = Console.ReadLine();
    Console.WriteLine(name)

    Console.WriteLine("What is the artists name");
    string artist = Console.ReadLine();
    Console.WriteLine(artist)

    int records;
    Console.WriteLine("How many records did it sell");
    while (!int.TryParse(Console.ReadLine(), out records) || records < 0)
    {
        Console.WriteLine("That is not valid please enter a number");
    }
    Console.WriteLine(records)
    return new Song(name, artist, records);
}

et vous pouvez simplement créer un test unitaire simple pour la méthode

Veuillez lire https://docs.microsoft.com/en -us / visualstudio / test / unit-test-basics? view = vs-2017


4 commentaires

Bien que cela ne réponde pas au "comment tester la méthode" (ce qui est assez trivial après votre refactoring), c'est assez bon pour "comment rendre ma méthode (unité) testable".


C'est ainsi que j'ai compris sa question, lorsqu'on lui a demandé «comment tester cette méthode», il a besoin de préparer sa méthode pour être «testable» - Eitam Ring il y a 7 minutes


@ Umarfarooq99 Il y a deux façons d'aborder les tests unitaires dans n'importe quel programme, vous devriez lire le lien que j'ai posté, vous créez juste un ensemble d'entrées et affirmez le résultat à la fin (puisque vous savez ce que vous attendez). Lien pour l'exemple d'assertion et de test unitaire: docs.microsoft.com/en-us/visualstudio/test/... Regardez principalement Assert.AreEqual ().


@ Umarfarooq99 Si quelque chose vous empêche de changer la méthode, vous devez chercher d'autres moyens de tester cette méthode, dans l'état où vous avez posté, vous ne pouvez pas tester correctement la méthode.



0
votes

Un exemple de test unitaire pour vous. Le code utilise NSubstitute pour l'objet simulé.

public class Song
{
    public string Name { get; }

    public string Artist { get; }

    public int Records { get; }

    public Song(string name, string artist, int records)
    {
        Name = name;
        Artist = artist;
        Records = records;
    }
}

public interface IInOutService
{
    void Ask(string question);

    string GetString();

    string AskValue(string question);
}

public class InOutService : IInOutService
{
    public void Ask(string question)
    {
        Console.WriteLine(question);
    }

    public string GetString()
    {
        return Console.ReadLine();
    }

    public string AskValue(string question)
    {
        Ask(question);
        return GetString();
    }
}

public class FactorySong
{
    private readonly IInOutService _inOutService;

    public FactorySong(IInOutService inOutService)
    {
        _inOutService = inOutService;
    }

    public Song Create()
    {
        var name = _inOutService.AskValue("What is the name of your song");
        var artist = _inOutService.AskValue("What is the artists name");

        int records;
        _inOutService.Ask("How many records did it sell");

        while (!int.TryParse(_inOutService.GetString(), out records) || records < 0)
        {
            _inOutService.Ask("That is not valid please enter a number");
        }

        return new Song(name, artist, records);
    }
}

[TestClass]
public class FactorySongTest
{
    [TestMethod]
    public void TestCreate()
    {
        var consoleService = Substitute.For<IInOutService>();
        var testString = "test";
        var testRecords = 1;

        consoleService.AskValue(Arg.Any<string>()).Returns(testString);
        consoleService.GetString().Returns(testRecords.ToString());

        var factory = new FactorySong(consoleService);
        var song = factory.Create();

        Assert.IsNotNull(song);
        Assert.IsTrue(testString == song.Name);
        Assert.IsTrue(testString == song.Name);
        Assert.AreEqual(testRecords, song.Records);
    }
}


0 commentaires