嘲笑用于MEAN应用程序单元测试的MongoDB连接(Mocking MongoDB connection for MEAN application unit testing)
我一直在绞尽脑汁,试图找出一种方法来处理我的单元测试MongoDB连接。 我想知道做什么适当的方法是因为我的应用程序布局可能是问题。 这是针对包含大量模块的较大项目。
总体布局
package.json server.js -models -index.js -users.js -events.js -... -services -index.js -userActivity.js -... +public +routes +util +test
车型/ users.js
"use strict"; modules.export = function(mongoose) { var Schema = mongoose.Schema; var userSchema = new Schema({ name: String }); var userModel = mongoose.model('User', userSchema); var userDAO {}; userDAO.addUser(user) { var newUser = new userModel(user); return newUser.save(); } userDAO.getUser(id) { return userModel.findById(id).lean().exec(); } return userDAO; };
车型/ index.js
"use strict"; var bluebird= require('bluebird'); var mongoose = bluebird.promisifyAll(require('mongoose')); var Users = require ('./users'); var Events = require('./events'); module.exports.Users = new Users(mongoose); module.exports.Events = new Events(mongoose);
服务/ userActivity.js
"use strict"; var db = require('../models'); module.exports = function(userID) { return db.Events.getEventsForUser(userId) };
现在问题在哪里
测试/ test.js
"use strict"; var chai = require('chai'); chai.use(require('chai-as-promised'); var expect = chai.expect; var mongoose = require('mongoose'); mongoose.connect("mongodb://localhost/testDB") var db = require('../models'); var services = require('../services') describe("sample tests", function() { var user1, user2; var user1TestEvents = []; before(function(done) { db.Users.addUser({name:"John"}). then(function(john) { user1 = john; return db.Users.addUser({name: "Mary"}); }). then(function(mary) { user2 = mary; return db.Events.addEvent{user: user1._id, event: "logged in", time: new Date()}); }). then(function(event) { user1TestEvents.push(event); done() }); }; it('gets a users events', function() { var events = services.getEventsForUser(user1._id); return expect(events).eventually.to.have.length(user1TestEvents.length); });
如果我连接到我自己的机器上的活动数据库,但测试工作得很好,但我们的CI服务器没有运行mongo数据库。 我一直在试图找出伪造连接的方法,但我还没有找到任何好的选择
我一直在尝试使用Mockgoose来模拟数据库,但除非将所有组件都一直向下传递mockgooe的猫鼬对象,否则它将无法工作。
var mockgoose = require('mockgoose'); var mongoose = require('mongoose'); mockgoose(mongoose); mongoose.connect("mongodb://localhost/test");
当我尝试这样做后,第一个承诺在我的“之前”解决后,所有后续的承诺永远不会解决,摩卡超时。
我还没有能够让tingoDB工作,而且我感觉我失去了一些明显的东西。
我见过的所有例子都是非常简单的测试用例,其中模型创建在与猫鼬对象执行连接相同的位置,并且我将应用程序分开,我似乎无法与猫鼬解耦到实际的MongoDB实例。
如果有人有单元测试没有实际的MongoDB实例的MEAN应用程序的经验,我会很乐意提供一些关于如何修正我的布局和让我的单元测试工作的建议。
I've been wracking my brains trying to figure out a way to handle mocking my MongoDB connection for my unit tests. I'm wondering what the proper method is for doing this since my application layout may be the issue. This is for a larger project with lots of modules.
The general layout
package.json server.js -models -index.js -users.js -events.js -... -services -index.js -userActivity.js -... +public +routes +util +test
models/users.js
"use strict"; modules.export = function(mongoose) { var Schema = mongoose.Schema; var userSchema = new Schema({ name: String }); var userModel = mongoose.model('User', userSchema); var userDAO {}; userDAO.addUser(user) { var newUser = new userModel(user); return newUser.save(); } userDAO.getUser(id) { return userModel.findById(id).lean().exec(); } return userDAO; };
models/index.js
"use strict"; var bluebird= require('bluebird'); var mongoose = bluebird.promisifyAll(require('mongoose')); var Users = require ('./users'); var Events = require('./events'); module.exports.Users = new Users(mongoose); module.exports.Events = new Events(mongoose);
services/userActivity.js
"use strict"; var db = require('../models'); module.exports = function(userID) { return db.Events.getEventsForUser(userId) };
Now here's where the problem is
test/test.js
"use strict"; var chai = require('chai'); chai.use(require('chai-as-promised'); var expect = chai.expect; var mongoose = require('mongoose'); mongoose.connect("mongodb://localhost/testDB") var db = require('../models'); var services = require('../services') describe("sample tests", function() { var user1, user2; var user1TestEvents = []; before(function(done) { db.Users.addUser({name:"John"}). then(function(john) { user1 = john; return db.Users.addUser({name: "Mary"}); }). then(function(mary) { user2 = mary; return db.Events.addEvent{user: user1._id, event: "logged in", time: new Date()}); }). then(function(event) { user1TestEvents.push(event); done() }); }; it('gets a users events', function() { var events = services.getEventsForUser(user1._id); return expect(events).eventually.to.have.length(user1TestEvents.length); });
The tests work just fine if I connect to a live database on my own machine, but our CI servers won't have a mongo database running on them. I have been trying to figure out some way of faking the connection but I haven't found any good alternatives
I have been trying to use Mockgoose to get mock the database but unless I pass the mockgooesed mongoose object all the way down through all the components it will not work.
var mockgoose = require('mockgoose'); var mongoose = require('mongoose'); mockgoose(mongoose); mongoose.connect("mongodb://localhost/test");
When I tried this, after the first promise resolves in my "before", all subsequent promises never resolve and mocha times out.
I haven't been able to get tingoDB working either and I'm feeling like I'm missing something obvious.
All of the examples I've seen were very simple test cases where the models were created in the same location that the mongoose object performed the connection and with the way I have the application broken apart I can't seem to get a decoupling from mongoose to the actual MongoDB instance.
If anyone has experience with unit testing MEAN applications without an actual MongoDB instance I'd be very happy for some advice on how to fix my layout and get my unit tests working.
原文:https://stackoverflow.com/questions/30902622
最满意答案
你的代码没问题。 缺少变量
query
或queryKount
?TypedQuery<FraudDetectionInfoEntity> queryKount = em_oltp.createQuery("SELECT o FROM FraudDetectionInfoEntity o WHERE o.order.orderId=:orderId",FraudDetectionInfoEntity.class); query.setParameter("orderId", orderEntity.getOrderId()); <or> queryKount.setParameter("orderId", orderEntity.getOrderId());
Your code is ok. Missing variable
query
orqueryKount
?TypedQuery<FraudDetectionInfoEntity> queryKount = em_oltp.createQuery("SELECT o FROM FraudDetectionInfoEntity o WHERE o.order.orderId=:orderId",FraudDetectionInfoEntity.class); query.setParameter("orderId", orderEntity.getOrderId()); <or> queryKount.setParameter("orderId", orderEntity.getOrderId());
相关问答
更多-
对不同模块中的EJB的调用类似于远程调用,因为它们使用按值传递语义并进行序列化/反序列化。 在这种情况下,不使用网络,但远程调用的所有其他方面仍在发生。 这对您来说意味着即使您从另一个EJB模块获得非空EntityManager ,它也会被序列化/反序列化,并且当它进入另一个EJB模块时,它不再引用有效的持久化上下文(因为它在调用EJB模块中不存在)。 Calls to EJBs that are in different modules are similar to remote invocations ...
-
我有一个EJB项目,我正在尝试使用JPA。 要创建实体管理器,我将通过注释注入它 注释部分本身看起来正确。 当我运行一个我认为没问题的测试查询时 我认为不是,它至少在WHERE子句中缺少一个AND。 但我会这样写它: Query userQuery = em.createQuery("SELECT u FROM TestUser u WHERE u.username = :name AND u.password = :password"); userQuery.setParameter("name", "t ...
-
I have written all named queries in a class with @NamedQuery annotation 你在上面的陈述中没有清楚地提到你所指的类型? 您需要在Entity类(使用@Entity注解进行注释的类)中编写命名查询。 更新:我现在有点困惑你的类DBNamedQuery 。 你说你正在使用一个类来放置所有命名查询。 我的理解是你正在使用这个类为你的应用程序的所有实体编写命名查询。 如果这是正确的,那么如何在类DBNamedQuery上使用@Entity批注, ...
-
您的查询缺少括号和values关键字。 尝试 String query = ("insert into my_table (abc_id, dup_id,type_code) "+ "values (abc_seq.nextval, 2,:type)"); Query myQuery = em.createNativeQuery(query); nativeQuery.setParameter("type", code); Your query lacks a pa ...
-
您在MST和WHERE之间缺少空格。 You are missing a space between MST and WHERE.
-
两个嵌套的EJB Bean - 只有第一个得到一个entiy管理器注入(two nested EJB Beans - only the first get an entiy manager injected)[2023-08-11]
EntityManager没有注入AllocationPlanController因为您“手动”使用它的构造函数创建AllocationPlanController实例。 您应该将AllocationPlanController注入AllocationController bean并让容器管理它的生命周期。 The EntityManager is not injected into the AllocationPlanController because you are "manually" creati ... -
我建议你使用新的API Manager(1.9)并尝试以下方法。 使用http://...../search的后端URL创建API 定义URL模式时,可以定义以下模式 /{stationcode}* 您可以在API创建页面的设计视图中添加“type”和“status”作为可选参数。 您可以选择参数类型为'query',Required为'False' I would suggest you to use the new API Manager (1.9) and try the following. Cr ...
-
你的代码没问题。 缺少变量query或queryKount ? TypedQuery
queryKount = em_oltp.createQuery("SELECT o FROM FraudDetectionInfoEntity o WHERE o.order.orderId=:orderId",FraudDetectionInfoEntity.class); query.setParameter("orderId", orderEntity.ge ... -
使用new操作符创建对象时不会发生注入。 您需要让容器创建datatypes bean并将其注入backEndForm : @WebService(serviceName="backend") @Stateless public class backEndForm implements backEndFormRemote { @EJB private datatypesRemote data; public List
retrieveAllDatatypes( ... -
EJB中的动态实体管理器(Dynamic Entity Manager in EJB)[2022-10-16]
您可以通过从persistence.xml删除数据库URL并在运行时指定它来执行此操作: Mapparams = new HashMap (); // put the correct URL here // you can also specify any other parameter from 'persistence.xml' String dbUrl = "jdbc:mysql://localhost:3308/database_sch ...