Sinon: Возможность вызова произвольной функции из заглушек

Созданный на 15 апр. 2012  ·  23Комментарии  ·  Источник: sinonjs/sinon

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

Я с радостью предоставлю для этого пул-реквест, но сначала я хотел бы убедиться, что он будет принят.

Самый полезный комментарий

@mantoni шпион не позволяет вам определять различное поведение для разных вызовов.

У меня также есть вариант использования для stub.onSecondCall().calls(function() {}) . Я хочу выполнять свои собственные утверждения во время этих звонков.

Все 23 Комментарий

Это уже существует:

sinon.stub(obj, "meth", function () {
    // Whatever you want in here
});

Блестяще! И это тоже есть в документации! Извините, как-то пропустил.

Я голосую за повторное открытие по следующим причинам:

// Argument matching
var stub = sinon.stub();
stub.withArgs("a").calls(f);
stub.withArgs("b").returns(something);

Уже есть способ выполнить настраиваемую логику. Я вообще считаю, что нетривиальная логика в тестах - плохая идея, и не хочу поощрять ее дальнейшими функциями в этом направлении.

Я бы не сказал, что издевательство над контрактом в тесте - плохая идея или что это должно быть нетривиально. Примером может служить обработчик запросов в маршрутизаторе:

var mockRequest = sinon.stub();
mockRequest.withArgs(someReq, someRes).calls(function(req, res) {
  res.send('mock result 1');
});
mockRequest.withArgs(someOtherReq, someOtherRes).calls(function(req, res) {
  res.send('mock result 2');
});

Конечно, этого можно добиться с помощью «yieldsTo», но я думаю, что это неочевидно и не очень хорошо читается.

Однако я понимаю, что вы не хотите добавлять уже большой api.

Я тоже придерживался этого:

var mockRequest = sinon.stub();
mockRequest.onThirdCall().calls(function() {
    console.log('Yes!');
    done();
});

Требуются любые подсказки о том, как этого можно достичь. :(

Это было бы очень полезно. А пока мне нужно сделать для этого свою собственную функцию-заглушку :(

Почему должны быть объект и «метод», чтобы можно было заглушить (fn)? Я не могу понять, в чем разница со шпионом (фн)?

+1 к комментарию @shakiba . «Ответ» здесь, sinon.stub(obj, "meth", function () { ... }) , работает только при установке метода на объект. При создании автономной заглушки метода с sinon.stub() (например, чтобы передать что-то еще в качестве прослушивателя событий или обратного вызова), вы не можете использовать это решение.

Обходной путь уродливый:

var fakeObject = { fn: function () { } };
sinon.stub(fakeObject, "fn", function () { ... });
var stubIWanted = fakeObject.fn;

Я бы предпочел чистый синтаксис вроде:

var stubIWanted = sinon.stub(function () { ... });

@peterflynn Вы можете сделать это со шпионом:

var spyYouWant = sinon.spy(function () { ... });

@mantoni шпион не позволяет вам определять различное поведение для разных вызовов.

У меня также есть вариант использования для stub.onSecondCall().calls(function() {}) . Я хочу выполнять свои собственные утверждения во время этих звонков.

+1 за вариант использования

+1 за изменение , предложенное

@ChiperSoft Вы вполне способны самостоятельно определять разное поведение для разных вызовов. Просто проверьте кол-во звонков в шпионе.

@bion Мы пытаемся уменьшить API до версии 2.0. Посмотрите, можете ли вы создать оболочку / плагин для расширения основных функций, если вы считаете, что это полезно, и опубликуйте их в NPM, если они вам подходят.

В итоге я создал свою собственную библиотеку заглушек функций, которая позволяла мне определять обратные вызовы для каждого вызова. Это значительно упрощает тесты и позволяет мне полностью удалить sinon из моих проектов. http://npm.im/stepperbox

моя заглушка выполняет исходный метод, почему

@ppyoosuf, пожалуйста, отправляйте вопросы об использовании в список рассылки или переполнение стека после просмотра документации. Если вы обнаружите актуальную проблему / ошибку, попробуйте открыть новую проблему и разместите достаточно кода, чтобы мы могли проверить проблему.

это моя функция контроллера в node.js

export.searchDocument = функция (req, res) {var type = req.query.docType; вар
dep = req.query.dep; var serStr = req.query.serStr; var результат; //
console.log (req.session.userMode); res.writeHead (200, {"Content-Type":
"application / json"});

    if(type===''||type===null || isNaN(type) ||dep===''||dep===null)

    // console.log("type:"+type+"dep="+dep);

    if(type==='-1' && dep==='-1')
    {
      docService.getAllDoc(serStr,function(err,data){
          if(err) throw err;
          result=data;
          res.end(JSON.stringify(result));
      });
    }
    else if(type==='-1')
        docService.getDocByDep(serStr,dep,function(err,data){
            if(err) throw err;
            result=data;
            res.end(JSON.stringify(result));
      });
    else if(dep==='-1')
      docService.getDocByType(serStr,type,function(err,data){
          if(err) throw err;
          result=data;
          res.end(JSON.stringify(result));
      });
    else
      **docService.getDocByTypeDep**(serStr,type,dep,function(err,data){
          console.log(data);
          console.log(err);
          if(err) throw err;
          result=data;
          res.end(JSON.stringify(result));
      });
                 };

здесь docService.getDocByTypeDep - это функция службы базы данных

this.getDocByTypeDep = function (ser, typeId, depId, cb) {

var myErr = null, data = null;
if (typeId == null || typeId == '' || depId == null || depId == '') return
cb ("ошибка", данные);
var qry = "";

con.query (qry, typeId, function (err, res) {

если (ошибка)
{
myErr = err;
cb (myErr, данные);
}
еще
{
data = res;
cb (myErr, данные);
}
});

     };

Я написал тестовые примеры с помощью sinon stub, но он выполнял исходную функцию

it('returns the result', function(done) {
   var stub = sinon.stub(docService, 'getDocByTypeDep');
    var req = {
        query:{
            docType: '2',
            dep:'4',
            serStr:"a"
        }
    };
    // we provide the response object which the controller uses
    var res = {
        end: function(data) {
            expect(data).to.be.a("string");
            stub.restore();
            done();
        },
        writeHead:function(){

        }
    };
    // var error = new Error('Authentication failed.');
    stub.callsArgWithAsync(3,error,error);
    controllerToTest.searchDocument(req,res); // call the function

для проверки

           });

    please help me

В чт, 23 июня 2016 г., в 12:16, Карл-Эрик Копсенг <
[email protected]> написал:

@ppyoosuf https://github.com/ppyoosuf, пожалуйста, задавайте вопросы об использовании по адресу
список рассылки или переполнение стека после просмотра документации. Если вы найдете
актуальная проблема / ошибка, попробуйте открыть новую проблему и отправьте нам достаточно кода, чтобы
проверьте проблему.

-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/sinonjs/sinon/issues/118#issuecomment -227964049 или отключить звук
нить
https://github.com/notifications/unsubscribe/APpoQazXq7BUm113wp7--RlxDaukOcMYks5qOivEgaJpZM4BSxXv
.

@ppyoosuf Мы стараемся, чтобы список проблем GitHub был аккуратным и сосредоточился на ошибках и обсуждениях функций. Это вопрос использования, отправьте его в список рассылки Sinon.JS , чтобы более

Ok

Без этой функции использование фальшивых таймеров затруднительно.
У меня есть метод, который вызывается внутри черного ящика несколько раз с таймаутом, чтобы проверить черный ящик, мне нужно иметь возможность управлять часами.
Поэтому я хочу вызывать clock.tick каждый раз при попадании в определенную заглушку, также я определил поведение для этой заглушки через withArgs и yields .

Хотелось бы увидеть что-то вроде:

var clock = sinong.useFakeTimers();
var stubbedMethod = sinon.stub();
stubbedMethod.onHit(()=>clock.tick(1000)).withArgs('page1').yields(null, [12, 45, 69]);

Это возможно только за счет специальной конструкции заглушки, что не всегда удобно или возможно:

sinon.stub(object, 'method', function(callback){
  clock.tick(1000);
  callback();
})

Возможность изменять состояние теста / среды по вызову важна для множества различных тестов и крайне важна для наличия в макетной библиотеке.

в sinon 2.1 callsFake() будет делать именно это

Я не видел этого решения, размещенного выше, поэтому добавляю, если оно помогает другим:

Использование шпионского интерфейса для получения аргументов n-го вызова

var someFunctionSpy = sinon.spy(someFunction)
someFunction()
var nthCallArgs = someFunctionSpy.getCall(n)
Была ли эта страница полезной?
0 / 5 - 0 рейтинги