Я пытаюсь установить шаблон модульного тестирования для своей компании. Наши клиентские проекты построены с использованием классов ES6 и зависят от нашего основного продукта. Код внешнего интерфейса оборачивается в процессе сборки целым другим блоком кода, который, по сути, является замыканием и фиксирует зависимость. Поэтому нам не нужно вручную импортировать его, чтобы использовать.
Допустим, зависимость называется productScope, и это объект, который имеет некоторые модели DOM, внутренние API-интерфейсы и параметры, среди прочего, необходимые для каждого проекта. На данный момент Мокко кидает ReferenceError: productScope is not defined. Как можно поиздеваться над этим объектом? Или я должен просто использовать реальный объект?
Пример:
class someClass {
constructor() {
const id = productScope.items[0].id
const item = productScope.domModel.querySelector('.some-div')
item.classList.add(`added-${id}`)
}
}
Это завернуто в основной код, как показано ниже:
(function(productScope) {
// front end code goes here
}(productScope)
Файл тестирования:
import someClass from '../../js/someClass'
describe('someClass', function() {
const someClass = new someClass()
it('should be a class', function() {
console.info(someClass)
});
});
Вот ответ в стиле вашего вопроса: Прочтите это: gofreerange.com/mocha/docs/Mocha/Mock.html
@PatrickHund добавил код



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Похоже, productScope - это глобальная переменная.
Что-то вроде этого должно сработать для вас.
import someClass from '../../js/someClass';
describe('someClass', function() {
let someClass;
beforeEach(() => {
global.productScope = {
// you mock definition
someClass = new someClass();
};
});
it('should be a class', function() {
console.info(someClass)
});
});
Спасибо, но все та же ошибка, плюс сообщение 1) "before each" hook for "should be a class" красным цветом.
Откуда вы берете productScope? Вы импортируете его в свой файл или это глобальная переменная?
По сути, есть целый блок кода, который обертывает внешний код, и это закрытие, которое захватывает productScope.
Если это закрытие, вы можете заглушить его с помощью sinon. Можете показать, как импортировать productScope в файл js/someClass?
Мне не нужно импортировать его в класс, потому что класс как бы обернут в него. Может быть, как если бы вы использовали $ as jQuery внутри IIFE.
Похоже, у вас сложная настройка кода. Можете ли вы добавить весь код для ясности?
Вы можете попробовать что-то вроде этого
describe('#someClass', () => {
let someClass;
beforeEach(() => {
global.productScope = {
// mocking productScope object
};
});
it('should be a class', () => {
someClass = new SomeClass;
console.info(someClass);
});
afterEach(() => {
delete global.productScope;
});
});
или, в качестве альтернативы, если вам нужна более конкретная фиктивная логика для каждого тестового примера
describe('#someClass', () => {
let someClass;
it('should be a class', () => {
global.productScope = {
// mocking productScope object
};
// Test logic start
someClass = new SomeClass;
console.info(someClass);
// Test logic end
delete global.productScope;
});
});
У меня есть и другие ответы, так как управление переменными global кажется самым простым и понятным решением.
Однако вы можете использовать нанизывать для получения строкового представления класса и оценка для привязки к области закрытия:
class someClass {
constructor() {
this.id = scopedId
}
}
// pass class as an argument
function scopeFactory(classDef) {
// define scoped data
let scopedId = 2;
// eval is used to bind class to the local closure
// so `scopedId` will be in charge
return eval("(" + classDef + ")");
}
const scopedSomeClass = scopeFactory(someClass);
console.info(new scopedSomeClass)Обратите внимание, что eval(someCLass.toString())не работает без скобок.
Вы можете добавить его в свой проект как вспомогательную функцию.
Измените свой вопрос, включив в него соответствующие части кода модульного теста.