qUnit тестирование на закрытие jQuery

not необходимо поместить реализацию в файл заголовка, см. альтернативное решение в конце этого ответа.

В любом случае причина, по которой ваш код не работает, что при создании экземпляра шаблона компилятор создает новый класс с заданным аргументом шаблона. Например:

template
struct Foo
{
    T bar;
    void doSomething(T param) {/* do stuff using T */}
};

// somewhere in a .cpp
Foo f; 

При чтении этой строки компилятор создаст новый класс (назовем его FooInt), что эквивалентно следующему:

struct FooInt
{
    int bar;
    void doSomething(int param) {/* do stuff using int */}
}

Следовательно, компилятор должен иметь доступ к реализации методов, чтобы создать экземпляр с аргументом шаблона (в данном случае int). Если эти реализации не были в заголовке, они не были бы доступны, поэтому компилятор не смог бы создать экземпляр шаблона.

Общим решением для этого является запись объявления шаблона в заголовок файла, затем реализовать класс в файле реализации (например, .tpp) и включить этот файл реализации в конец заголовка.

// Foo.h
template 
struct Foo
{
    void doSomething(T param);
};

#include "Foo.tpp"

// Foo.tpp
template 
void Foo::doSomething(T param)
{
    //implementation
}

Таким образом, реализация по-прежнему отделена от объявления, но доступен компилятору.

Другое решение состоит в том, чтобы сохранить реализацию отдельно и явно создать все экземпляры шаблона, которые вам понадобятся:

// Foo.h

// no implementation
template  struct Foo { ... };

//----------------------------------------    
// Foo.cpp

// implementation of Foo's methods

// explicit instantiations
template class Foo;
template class Foo;
// You will only be able to use Foo with int or float

Если мое объяснение isn ' t достаточно ясно, вы можете взглянуть на C ++ Super-FAQ по этому вопросу .

0
задан lemoncodes 16 January 2019 в 10:43
поделиться

1 ответ

К сожалению, вы не можете проверить их, используя код, как он есть. Эти функции являются частными для области действия функции обертывания (недоступны за ее пределами). Тем не менее, вы можете реорганизовать свой код, чтобы это произошло:

// module 1
function initSomethings($) {  // <-- notice I added a name
    function iWantToTestThisOne_1() {
        //do something
        doSomething();
    }

    function iWantToTestThisOne_2() {
        //do something
        doSomething();
    }

    function iWantToTestThisOne_3() {
        //do something
        doSomething();
    }

    function doSomething() {
        //doing something
    }

    return { // give back the methods in here...
        iWantToTestThisOne_1,
        iWantToTestThisOne_2,
        iWantToTestThisOne_3,
        doSomething
        // Note that we don't have to return ALL of them, so you could keep some of them private by not returning them here
    };
};  // <-- notice that I am NOT calling the wrapper function

Затем, позже, в каком-то «главном» модуле мы можем инициализировать наши функции:

// "main" module
initSomething();
initAnother();

Это заботится о код вашего приложения. Для тестирования мы можем использовать возвращаемое значение всех функций:

QUnit.test('iWantToTestThisOne_1()', function(assert){
    // Start by initializing your functions...
    let methods = initSomething();
    // Then stub it out...
    let stub_doSomething = sinon.stub(methods, "doSomething").returns("something");

    // Now you call the function you're testing:
    methods.iWantToTestThisOne_1();
    // And do your assertions
    assert.equal(stub_doSomething.called, true, "doSomething() is called");
    // more assertions...
});
0
ответ дан jakerella 16 January 2019 в 10:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: