【问题标题】:How do I stub a method in an object that is loaded in my class/method under test?如何在我的测试类/方法中加载的对象中存根方法?
【发布时间】:2018-08-02 01:29:30
【问题描述】:

我们的MEANJS 应用程序有一个类(例如CompanyService),它加载另一个类的对象(例如CompanyRepo)并调用它的方法。我正在尝试为CompanyService 类编写单元测试,并且需要在CompanyRepo 方法中存根一个方法来模拟承诺拒绝。然而,尽管有存根,CompanyService 方法调用似乎调用了实际的CompanyRepo 方法调用。

代码流程如下,

companyService 方法

function isDomainExists(domain) {
    return new Promise(function(resolve, reject) {
        companyRepo.getCompanyByDomain(domain)
                .then(function (company) {
                    return resolve(company);
                }, function(rejected) {
                    return reject("Error");
                })
    } });

单元测试方法

var stub = sinon.stub(companyRepo,"getCompanyByDomain").rejects("error"); it('Should return company not registered if there is a DB error', function() {
    return companyService.isDomainExists("test company").should.eventually.be.rejected(); }); stub.restore();

输出

公司服务 isDomainExists 方法 如果出现数据库错误,应返回未注册的公司: AssertionError: 预期的承诺被拒绝,但它被 { Object ($__, isNew, ...) }

我想我可以理解这里发生了什么。 companyService 类有一个 require 语句,它加载 companyRepo 类,该类甚至在存根发生之前就被执行。有什么方法可以避免这种情况发生吗?在这种情况下,推荐的最佳做法是什么?

【问题讨论】:

    标签: javascript unit-testing tdd sinon sinon-chai


    【解决方案1】:

    我无法让它与 should 一起正常工作,但确实让它工作,看看它是否有帮助:

    公司服务:

    var companyRepo = require('./companyRepo');
    
    function isDomainExists(domain) {
        return new Promise(function (resolve, reject) {
            companyRepo.getCompanyByDomain(domain)
                .then(function (company) {
                    console.log('----in main resolve')
                    return resolve(company);
                }, function (rejected) {
                    console.log('----in error catch')
                    // return reject(new Error('Errorx'));
                    return reject('Error');
                });
        });
    };
    
    exports.isDomainExists = isDomainExists;
    

    公司回购

    exports.getCompanyByDomain = () => { 
        console.log('-----in real getCompanyByDomain');
    
        return Promise.resolve('resolve from real function');
    }
    

    测试

    it('Should return company not registered if there is a DB error', async function () {
        var stub = sinon.stub(companyRepo, "getCompanyByDomain").rejects("fake_error");
    
        await expect(companyService.isDomainExists("test company")).to.eventually.be.rejectedWith('Error');
    
        stub.restore();
    });
    

    它拒绝错误(而不是 fake_error),因为您的拒绝函数无论如何都会发送“错误”。

    有时应该表现得很有趣,不知道为什么,也可以尝试在测试中(或在 beforeEach、afterEach 中)移动 stub / resotre。

    companyRepo 定义中还有一个小错别字。

    如果没有其他方法(我在某些情况下见过这种情况),请尝试重新连接到存根:

    var rewire = require('rewire')
    //notice not using require here
    var companyService = rewire('./companyService');
    
    it('should stub', async () => {
        let fake = {
            getCompanyByDomain: () => {
                console.log('------rewired stub')
                return Promise.reject('rewired_error');
            }
        }
    
        companyService.__set__('companyRepo', fake);
    
        await expect(companyService.isDomainExists("test company")).to.eventually.be.rejectedWith('Error');
        //reset
        companyService = rewire('./companyService');
    });
    

    【讨论】:

    • 非常感谢@Mankind1023 的建议。下周我会试试这些,看看它们是否有效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多