NUnit не захватывает вывод std :: cerr - PullRequest
4 голосов
/ 25 марта 2010

У меня есть тест Nunit в C #, который вызывает оболочку C # функции в C ++ DLL. Код C ++ использует std :: cerr для вывода различных сообщений.

Эти сообщения нельзя перенаправить с помощью переключателя nunit-console / out / err или / xml. В nunit (версия с графическим интерфейсом) вывод нигде не отображается.

Я бы хотел видеть этот вывод в nunit (версия с графическим интерфейсом). В идеале я хотел бы иметь доступ к этому выводу в тесте.

Спасибо за любую помощь.

Ответы [ 2 ]

1 голос
/ 29 марта 2010

Спасибо за подсказку. Вот что я в итоге сделал:

.CPP файл ------------------------

#include <iostream>
#include <sstream>

static std::stringstream buffer;
static std::streambuf * savedBuffer = NULL;


extern "C" __declspec(dllexport) bool Redirect()
{
    if (savedBuffer)
    {
        return false;
    }
    std::streambuf * buf(std::cerr.rdbuf());
    std::cerr.rdbuf(buffer.rdbuf());

    // This two lines are for illustration purposes only!
    std::cerr << "Hello world" << std::endl;

    return true;
}


extern "C" __declspec(dllexport) void Revert()
{
    if (savedBuffer)
    {
        std::cerr.rdbuf(savedBuffer);
    }
    savedBuffer = NULL;
}


extern "C" __declspec(dllexport) const char * getCerr()
{
    return _strdup(buffer.str().c_str());
}

extern "C" __declspec(dllexport) void freeCharPtr(char *ptr)
{
    free(ptr);
}

.CS файл ------------------------------------------

public static class Redirector
{
    // PRIVATE ------------------------------------------------------------
    private const String LibraryName = "MyCpp.dll";

    [DllImport(LibraryName, CharSet = CharSet.Ansi)]
    private static extern IntPtr getCerr();

    // PUBLIC -------------------------------------------------------------
    [DllImport(LibraryName, CharSet = CharSet.Ansi)]
    public static extern bool Redirect();

    [DllImport(LibraryName, CharSet = CharSet.Ansi)]
    public static extern void Revert();

    [DllImport(LibraryName, CharSet = CharSet.Ansi)]
    internal static extern void freeCharPtr(IntPtr ptr);

    public static string GetCerr()
    {
        IntPtr temp = getCerr();
        string result = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(temp);
        freeCharPtr(temp);
        return result;
    }
}

NUnit Test -----------------------

    [Test]
    // [Ignore]
    public void TestRedirect()
    {
        Redirector.Redirect();
        // Call more functions that output to std::cerr here.
        Redirector.Revert();
        System.Console.WriteLine(Redirector.GetCerr());
    }

Функция freeCharPtr () необходима для освобождения выделенной памяти от _strdup (), так как я не мог понять (если это вообще возможно), как упорядочить std :: string.

Примечание: это не потокобезопасно!

1 голос
/ 25 марта 2010

Перенаправление std :: cerr - это вопрос замены буфера потока своим собственным. Важно восстановить в исходном буфере перед выходом. Я не знаю, как выглядит ваша обертка, но вы, вероятно, сможете выяснить, как заставить ее читать output.str ().

#include <iostream>
#include <sstream>
#include <cassert>

using namespace std;

int main()
{
    streambuf* buf(cerr.rdbuf());
    stringstream output;

    cerr.rdbuf(output.rdbuf());
    cerr << "Hello, world!" << endl;

    assert(output.str() == "Hello, world!\n");
    cerr.rdbuf(buf);

    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...