面试题答案
一键面试1. Mock数据的动态生成策略
- 基本数据结构模拟:
- 商品列表中的每个商品对象应包含常见属性,如商品ID、名称、价格、描述等。例如,使用JavaScript对象字面量定义一个基本商品结构:
const baseProduct = {
id: null,
name: '',
price: 0,
description: ''
};
- 对于需要动态生成的数据,如商品ID,可以使用自增变量或UUID生成库。若使用自增变量:
let productId = 1;
const generateProduct = () => {
const product = {...baseProduct };
product.id = productId++;
return product;
};
- 多参数筛选相关数据生成:
- 假设筛选参数有类别(category)、品牌(brand)等。生成Mock数据时,预先定义可能的类别和品牌数组,然后随机从数组中选取值赋给商品对象。
const categories = ['electronics', 'clothing', 'food'];
const brands = ['Apple', 'Samsung', 'Nike'];
const generateProductWithFilters = () => {
const product = generateProduct();
product.category = categories[Math.floor(Math.random() * categories.length)];
product.brand = brands[Math.floor(Math.random() * brands.length)];
return product;
};
- 排序相关数据生成:
- 为了测试排序功能,生成的数据应具有不同的排序字段值。例如,价格字段要生成不同的数值,以便测试升序和降序排序。
const generateProductWithSortFields = () => {
const product = generateProductWithFilters();
product.price = Math.floor(Math.random() * 1000);
return product;
};
- 分页相关数据生成:
- 生成足够多的Mock数据,以模拟分页场景。可以根据分页参数动态截取数据。例如,假设有每页数量(pageSize)和页码(page)参数:
const generateMockProductList = (pageSize, page) => {
const totalProducts = 100;
const products = [];
for (let i = 0; i < totalProducts; i++) {
products.push(generateProductWithSortFields());
}
const startIndex = (page - 1) * pageSize;
const endIndex = startIndex + pageSize;
return products.slice(startIndex, endIndex);
};
2. 模拟网络延迟及异常情况
- 模拟网络延迟:
- 在Vue项目中,可以使用
async
/await
结合setTimeout
来模拟网络延迟。例如,假设使用Axios进行HTTP请求,创建一个Mock API函数:
- 在Vue项目中,可以使用
const mockApi = async (params) => {
await new Promise(resolve => setTimeout(resolve, 1000)); // 模拟1秒延迟
const products = generateMockProductList(params.pageSize, params.page);
return { data: products };
};
- 模拟网络异常情况:
- 模拟404错误:修改Mock API函数,在特定条件下抛出404错误。例如:
const mockApiWithError = async (params) => {
if (Math.random() < 0.1) { // 10% 的概率模拟404错误
throw { response: { status: 404 } };
}
await new Promise(resolve => setTimeout(resolve, 1000));
const products = generateMockProductList(params.pageSize, params.page);
return { data: products };
};
- **模拟网络超时**:可以通过设置`Promise.race`来模拟网络超时。例如:
const mockApiWithTimeout = async (params) => {
const timeoutPromise = new Promise((_, reject) => {
setTimeout(() => {
reject(new Error('Network timeout'));
}, 500); // 500毫秒超时
});
const apiPromise = new Promise(resolve => {
setTimeout(() => {
const products = generateMockProductList(params.pageSize, params.page);
resolve({ data: products });
}, 1000); // 模拟1秒响应
});
return Promise.race([timeoutPromise, apiPromise]);
};
3. 与单元测试、集成测试相结合
- 单元测试:
- 测试Mock数据生成函数:使用测试框架(如Jest)对Mock数据生成函数进行单元测试。例如,测试
generateProduct
函数是否正确生成商品对象:
- 测试Mock数据生成函数:使用测试框架(如Jest)对Mock数据生成函数进行单元测试。例如,测试
describe('generateProduct', () => {
it('should generate a product object with correct structure', () => {
const product = generateProduct();
expect(product).toHaveProperty('id');
expect(product).toHaveProperty('name');
expect(product).toHaveProperty('price');
expect(product).toHaveProperty('description');
});
});
- **测试Mock API函数**:测试Mock API函数的逻辑,如网络延迟和异常处理。例如,测试`mockApiWithError`函数是否能正确抛出404错误:
describe('mockApiWithError', () => {
it('should throw a 404 error with 10% probability', async () => {
try {
await mockApiWithError({ pageSize: 10, page: 1 });
} catch (error) {
expect(error.response.status).toBe(404);
}
});
});
- 集成测试:
- 测试组件与Mock API的集成:在Vue项目中,使用测试框架(如Vue Test Utils)测试组件与Mock API的集成。例如,假设存在一个商品列表组件
ProductList.vue
,测试其在调用Mock API获取数据后的渲染情况:
- 测试组件与Mock API的集成:在Vue项目中,使用测试框架(如Vue Test Utils)测试组件与Mock API的集成。例如,假设存在一个商品列表组件
<template>
<div>
<ul>
<li v - for="product in products" :key="product.id">{{ product.name }}</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
products: []
};
},
async created() {
try {
const response = await mockApi({ pageSize: 10, page: 1 });
this.products = response.data;
} catch (error) {
console.error('Error fetching products:', error);
}
}
};
</script>
import { mount } from '@vue/test - utils';
import ProductList from '@/components/ProductList.vue';
describe('ProductList.vue', () => {
it('should render product names after fetching data from mock API', async () => {
const wrapper = mount(ProductList);
await wrapper.vm.$nextTick();
const productItems = wrapper.findAll('li');
expect(productItems.length).toBeGreaterThan(0);
productItems.forEach((item, index) => {
expect(item.text()).toBe(wrapper.vm.products[index].name);
});
});
});
通过上述步骤,可以全面且高效地利用Mock数据对复杂的商品列表接口进行测试,确保接口的稳定性和正确性。