I'm trying to write a suite of integration tests, where I have custom code which uses the Umbraco API. The Umbraco database lives in a SQL Server CE 4.0 database (*.sdf file) and I've managed to get that association working fine.
My problem looks to be dependancies in the Umbraco code. For example, I would like to create a new user for my tests, so I try:
var user = User.MakeNew("developer", "developer", "mypassword", "my.email#email.com", adminUserType);
Now as you can see, I have pass a user type which is an object. I've tried two separate ways to create the user type, both of which fail due to a null object exception:
var adminUserType = UserType.GetUserType(1);
var adminUserType2 = new UserType(1);
The problem is that in each case the UserType code calls it's Cache method which uses the HttpRuntime class, which naturally is null.
My question is this: Can someone suggest a way of writing integration tests against Umbraco code? Will I have to end up using a mocking framework such as TypeMock or JustMock?
Here are some resources that may help:
http://www.aaron-powell.com/unit-testing-with-umbraco
http://stream.umbraco.org/video/726639/aaron-powell-unit-testing
Related
(This is similar to this question: How to set up separate test and development database in meteor, however it's 2 years old and meteor has changed a lot since then.)
I'm trying to create my own package and I want to run unit tests. I want to ensure that my queries are correct, so I want to actually run queries against a test database instead of just stubbing the functions.
I have two questions:
How can I tell Meteor to run against a test database instead of my real one?
What's the best way to easily populate that test database with data?
Ideally, I'd a setup step to clear than populate the test database, so I always know exactly what data is in each.
I'm a Tinytest novice (though I've used other unit test frameworks), so code samples are much appreciated.
Here's an example similar to what we use:
var resetCollection = function(name) {
var Collection = this[name];
if (Collection)
// if the collection is already defined, remove its documents
Collection.remove({});
else
// define a new unmanaged collection
this[name] = new Mongo.Collection(null);
};
reset = function() {
var collections = ['Comments', 'Posts'];
// reset all of the collections
_.each(collections(function(name) {resetCollection(name);}));
// insert some documents
var postId = Posts.insert({title: 'example post'});
Comments.insert({postId: postId, message: 'example comment'});
};
Tinytest.add('something', function(test) {
reset();
var post = Posts.findOne();
var comment = Comments.findOne();
return test.equal(comment.postId, post._id);
});
At the start of each test we call reset which cleans up the database and creates the necessary collections.
How can I tell Meteor to run against a test database instead of my real one?
When you test your packages, a separate database will be created for you. There is no need to manually specify your db path.
What's the best way to easily populate that test database with data?
The example above should give you some pointers. I've found the best way to avoid conflicts between packages is to use unmanaged collections in tests (name = null). The resetCollection function should correctly avoid redefining any managed collections which are exported by other packages. Also see this question for more details.
I have a number of simple controller classes that use Doctrine's entity manager to retrieve data and pass it to a view.
public function indexAction() {
$pages = $this->em->getRepository('Model_Page')->findAll();
$this->view->pages = $pages;
}
What exactly should we be testing here?
I could test routing on the action to ensure that's configured properly
I could potentially test that the appropriate view variables are being set, but this is cumbersome
The findAll() method should probably be in a repository layer which can be tested using mock data, but then this constitutes a different type of test and brings us back to the question of
What should we be testing as part of controller tests?
Controller holds core logic for your application. Though simple "index" controller actions don't have any specific functions, those that verify/actively use data and generate viewmodels have pretty much the most functionality of the system.
For example, consider login form. Whenever the login data is posted, controller should validate login/password and return: 1) to index page whenever logins are good. Show welcome,{user} text. 2) to the login page saying that login is not found in db. 3) to the login page saying that password is not found in db.
These three types of outputs make perfect test cases. You should validate that correct viewmodels/views are being sent back to the client with the appropriate actions.
You shouldn't look at a controller like at something mysterious. It's just another code piece, and it's tested as any other code - any complicated logic that gives business-value to the user should be tested.
Also, I'd recommend using acceptance testing with framework like Cucumber to generate meaningful test cases.
Probably the controller is the hardest thing to test, as it has many dependencies. In theory you should test it in full isolation, but as you already seen - it has no sense.
Probably you should start with functional or acceptance test. It tests your controller action in a whole. I agree with previous answer, that you should try acceptance testing tools. But Cucumber is for Ruby, for PHP you can try using Codeception. It makes tests simple and meaningful.
Also on a Codeception page there is an article on how to test sample controllers.
I'm trying to write unit tests for parts of my Node app. I'm using Mongoose for my ORM.
I've searched a bunch for how to do testing with Mongoose and Node but not come with anything. The solutions/frameworks all seem to be full-stack or make no mention of mocking stuff.
Is there a way I can mock my Mongoose DB so I can return static data in my tests? I'd rather not have to set up a test DB and fill it with data for every unit test.
Has anyone else encountered this?
I too went looking for answers, and ended up here. This is what I did:
I started off using mockery to mock out the module that my models were in. An then creating my own mock module with each model hanging off it as a property. These properties wrapped the real models (so that child properties exist for the code under test). And then I override the methods I want to manipulate for the test like save. This had the advantage of mockery being able to undo the mocking.
but...
I don't really care enough about undoing the mocking to write wrapper properties for every model. So now I just require my module and override the functions I want to manipulate. I will probably run tests in separate processes if it becomes an issue.
In the arrange part of my tests:
// mock out database saves
var db = require("../../schema");
db.Model1.prototype.save = function(callback) {
console.log("in the mock");
callback();
};
db.Model2.prototype.save = function(callback) {
console.log("in the mock");
callback("mock staged an error for testing purposes");
};
I solved this by structuring my code a little. I'm keeping all my mongoose-related stuff in separate classes with APIs like "save", "find", "delete" and no other class does direct access to the database. Then I simply mock those in tests that rely on data.
I did something similar with the actual objects that are returned. For every model I have in mongoose, I have a corresponding class that wraps it and provides access-methods to fields. Those are also easily mocked.
Also worth mentioning:
mockgoose - In-memory DB that mocks Mongoose, for testing purposes.
monckoose - Similar, but takes a different approach (Implements a fake driver). Monckoose seems to be unpublished as of March 2015.
I just recently read about "Mocking objects" for unit testing and currently I'm having a difficulties implementing this approach in my application. Please let me explain my problem.
I have a User model class, which is dependent on 2 data sources (database and facebook web service). The controller class simply use this User model as an interface to access data and it doesn't care about where the data came from.
Currently I never done any unit test to this User model because it is dependent on an external web service. But just a while ago, I read about object mocking and now I know that it is a common approach to unit test a class that depends on external resources (like in my case).
Now I want to create a unit test for the User model, but then I encountered a design issue:
In order for the User model to use a mocked Facebook SDK, I have to inject this mocked Facebook SDK to the User object (probably using a setter). Therefore I can't construct the Facebook SDK inside the User object. I have to construct it outside the User object, and inject the SDK into the User object.
The real client of my User model is the application's controller. Therefore I have to construct the Facebook SDK inside the controller and inject it to the user object. Well, this is a problem because I want my controller to be as clean as possible. I want my controller to be ignorant about the application's data source.
I'm not good at explaining something systematically, so you'll probably sleeping before reading this last paragraph. But anyway, I want to ask if anyone here ever encountered the same problem as mine? How do you solve this problem?
Regards,
Andree
P.S: I'm using Zend framework, PHP 5.3.
One way to solve this problem is to create two constructors in User: the default one instantiates the real-life data sources, the other one gets them as parameters. This way your controller can use the default constructor, while your tests use the parameterized one to pass in mock data sources.
Since you haven't specified your language, I show you an example in Java, hopefully this helps get the idea:
class User {
private DataBase database;
private WebService webService;
// default constructor
public User() {
database = new OracleDataBase();
webService = new FacebookWebService();
}
// constructor for unit testing
public User(DataBase database, WebService webService) {
this.database = database;
this.webService = webService;
}
}
This isn't really a question about mocking, but about dependencies--and trying to unit test has forced the issue. It sounds like currently you create your User object within your Controller.
If the User and Controller have the same lifetime (they're created at the same time), then you can pass the User into the Controller's constructor, which is where you can make the substitution.
If there is a User object per call, then perhaps the User object should be passed in by the environment, or returned from some Context object.
If you make the Facebook SDK Object(s) publicly accessible, your User object can still create it when it sets up but you can replace it with a mock before you actually do anything on the User object.
[Test]
public void Test()
{
User u = new User(); // let's say that the object on User gets created in the ctor
u.FacebookObj = new DynamicMock(typeof(FacebookSDK)).MockInstance;
Assert.That(u.Method(), Does.Stuff, "u.Method didn't do stuff");
}
You don't say what language you are using, but I use Ruby and Mocha for mocking objects, and it's quite easy.
See http://mocha.rubyforge.org/.
here the fourth example shows that any call to Product.name from the unit under test is intercepted and the value 'stubbed_name' is returned.
I guess there are similar mechanisms in Java, etc.
Since you will be Unit Testing your test class will play the role of the Controller, so that one should not be touched. So that can remain clean.
You are well underway of reinventing Dependency Injection. So it may be worthwhile to look at Spring or Guice to help you with the plumbing. (If you are in Java land).
Your test can indeed do the injection of the Mocked Facebook SDK and your Database service using setter or constructor arguments.
your tests will now do what the controllers (and maybe views) will do and verify the proper routines are called in the SDK's and that the resources are properly obtained and disposed of.
I have a legacy app that I am trying to build some testing into.
I have some tests that require the HttpContext.Current.User
Is there a way to mock this, or simply login a user on the fly?
HttpContext.User is of type IPrincipal. You can mock it by assigning to it any IPrincipal object, including any CustomPrincipal object.
I don't now how much you can refactor your legacy application. If you have .NET 3.5, you can use HttpContextWrapper class that is part of System.Web.Abstraction assembly.
You can read more and see an example how to Stub/Mock HttpContext.