I am newbie to VueJS (and in test cases as well), apologize if this is already asked question,
I added a method in my component which checks the $route.name and returns a boolean accordingly,
BUT the issue appears in the test cases (JEST)
Have tried it with this but not working
isAbc () {
return this.$route.name === 'abc-route
}
This is my method for which I want to write test case,
const $route = {
name: 'abc-route'
}
const wrapper = shallowMount(Component, {
mocks: {
$route
}
})
I have also tried this approach
https://github.com/facebook/jest/issues/890#issuecomment-209698782
and checked if I can get this.$route.path but no luck with that as well.
Anyone can please mention what am I missing or doing wrong to get this?
In case if anyone gets stucked on it, I have solve it by changing the approach,
Instead of assigning $router, one should do the following
component.vm.$router.replace({ path: '/some/path', name: 'some-name' })
and then test it with
expect(component.vm.isAbc()).toBe(false)
I am writing some Parse server cloud functions and trying to understand how I ll write a unit test that involve nested promises. e.g
Parse.Cloud.define("myfunction", function(request){
const common = require('./common')(Parse);
return common.firstPromise
.then(function(firstValue){
return common.secondPromise(firstValue, request.parama.p1);
})
.then(function(secondValue){
return common.thirdPromise(secondValue, request.param.p2);
})
.then(function(thirdValue){
return Parse.run("anotherFunction",{thirdValue:thirdValue});
})
.catch(function(e){
//log
return Promise.reject(e)
});
});
I am using a setup similar to like this. What are my options to make sure each nested promised called/not called with parameters etc. Is that testable ? or do I need to refactor and deal with each function in the promise chain ?
I'm trying to cover the following:
I'm using the following test code:
public function test_it_deletes_a_patient()
{
// ...
$cacheKey = vsprintf('%s.%s', [$this->doctorUser->id, 'backoffice.stats.patientsTotalCount']);
Cache::shouldReceive('has')->with($cacheKey)->once()->andReturn(false);
Cache::shouldReceive('increment')->with($cacheKey, -1)->once()->andReturn(true);
$response = $this->json('DELETE', route('patients.destroy', $this->patient), ['confirmation' => 'ELIMINAR']);
// ...
}
That triggers the following controller code:
public function destroy(Patient $patient, Request $request)
{
$this->authorize('delete', $patient);
$confirmation = $request->get('confirmation');
if ($confirmation != 'ELIMINAR') {
return response()->json(['success' => false]);
}
logger()->info("Deleting Patient Profile PATIENT_ID:[{$patient->id}]");
$patient->delete();
$this->updatePatientsCount(-1);
return response()->json(['success' => true]);
}
protected function updatePatientsCount($amount = 1)
{
$key = vsprintf('%s.%s', [auth()->user()->id, 'backoffice.stats.patientsTotalCount']);
if (Cache::has($key)) { // I want to mock for testing this
Cache::increment($key, $amount); // I want to mock for testing this
}
}
After test run I get:
alariva#trinsic:~/fimedi$ t --filter=test_it_deletes_a_patient
PHPUnit 7.3.1 by Sebastian Bergmann and contributors.
F 1 / 1 (100%)
Time: 6.53 seconds, Memory: 26.00MB
There was 1 failure:
1) Tests\Browser\Backoffice\PatientsTest::test_it_deletes_a_patient
Unable to find JSON fragment
["success":true]
within
[{"exception":"Mockery\\Exception\\NoMatchingExpectationException","file":"\/home\/alariva\/fimedi\/vendor\/mockery\/mockery\/library\/Mockery\/ExpectationDirector.php","line":92,"message":"No matching handler found for Mockery_0_Illuminate_Cache_CacheManager::has('2056e535e689ab723b3f44831b488f05f7fb8b90'). Either the method was unexpected or its arguments matched no expected argument list for this method\n\n","trace":[{"class":"App\\Http\\Middleware\\Language","file":"\/home\/alariva\/fimedi\/vendor\/laravel\/framework\/src\/Illuminate\/Pipeline\/Pipeline.php","function":"handle","line":151,"type":"->"},{"class":"Barryvdh\\Debugbar\\Middleware\\InjectDebugbar","file":"\/home\/alariva\/fimedi\/vendor\/laravel\/framework\/src\/Illuminate\/Pipeline\/Pipeline.php","function":"handle","line":151,"type":"->"},{"class":"Illuminate\\Auth\\Middleware\\Authenticate","file":"\/home\/alariva\/fimedi\/vendor\/laravel\/framework\/src\/Illuminate\/Pipeline\/Pipeline.php","function":"handle","line":151,"type":"->"},{"class":"Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse","file":"\/home\/alariva\/fimedi\/vendor\/laravel\/framework\/src\/Illuminate\/Pipeline\/Pipeline.php","function":"handle","line":151,"type":"->"},{"class":"Illuminate\\Cookie\\Middleware\\EncryptCookies","file":"\/home\/alariva\/fimedi\/vendor\/laravel\/framework\/src\/Illuminate\/Pipeline\/Pipeline.php","function":"handle","line":151,"type":"->"},{"class":"Il
What I interpret after a couple of tests, is that it looks like once I mock Cache it is being called by some middlewares before reaching the tested block, so since those called methods are not mocked, the test fails because it does not know what to answer for those middleware calls.
Imagine I could successfully mock all the calls before getting to the tested codeblock, I would be able to make it reach. But that's not the way to go over it.
How can I mock Cache and avoid failure due to previous Cache calls that I'm not testing?
EDIT: I realized after getting to a solution that this is a misleading question. My actual need was:
How can I successfully cover those lines?
Sidenote: if I try to disable middlewares ($this->withoutMiddleware();) I get an AccessDeniedHttpException
alariva#trinsic:~/fimedi$ t --filter=test_it_deletes_a_patient
PHPUnit 7.3.1 by Sebastian Bergmann and contributors.
F 1 / 1 (100%)
Time: 12.95 seconds, Memory: 24.00MB
There was 1 failure:
1) Tests\Browser\Backoffice\PatientsTest::test_it_deletes_a_patient
Unable to find JSON fragment
["success":true]
within
[{"exception":"Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException","file":"\/home\/alariva\/fimedi\/vendor\/laravel\/framework\/src\/Illuminate\/Foundation\/Exceptions\/Handler.php","line":201,"message":"This action is unauthorized.","trace":[{"class":"App\\Exceptions\\Handler","file":"\/home\/alariva\/fimedi\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Pipeline.php","function":"render","line":83,"type":"->"},{"class":"Illuminate\\Foundation\\Exceptions\\Handler","file":"\/home\/alariva\/fimedi\/app\/Exceptions\/Handler.php","function":"render","line":65,"type":"->"},{"class":"Illuminate\\Foundation\\Exceptions\\Handler","file":
Maybe I can cherry-pick middlewares to disable?
I managed to cover the controller's method by encapsulating the custom Cache operation into a macro, so as to get the benefits of spliting into code units.
I moved my code into a macro (in the boot() of a service provider):
Cache::macro('incrementExisting', function($key, $amount) {
if (Cache::has($key)) {
Cache::increment($key, $amount);
}
return $this;
});
I refactored to use the macro
protected function updatePatientsCount($amount = 1)
{
$key = vsprintf('%s.%s', [auth()->user()->id, 'backoffice.stats.patientsTotalCount']);
Cache::incrementExisting($key, $amount);
}
I could get the desired coverage while I can still test the refactored code with unit testing.
Update I
Regarding the concern of handling many calls that are not mocked, I just learned from Adam Wathan that there exists shouldIgnoreMissing() and that would allow to use the Mocking approach for this case.
Update II
Write your tests first. When doing so it gets easier to avoid hard-to-test code.
Thank you for your help-
I'd like to know if my app successfully adds a document to the database using a unit test in Meteor. I'm using practicalmeteor:mocha and chai. The issue I'm running into is that I don't know how to mock a this.userId, it keeps telling me I'm not logged in.
it('inserts the draft agenda document into the collection', function() {
// TODO: mock document to insert into collection
// TODO: mock userId and Agenda.insert
this.userId = "Not an empty string";
console.log("before spec, changing this.userId: " + this.userId) //is "Not an empty string"
Meteor.call('createAgenda', mockAgenda, function(res) {
console.log("callback with response: " + res); //You're not logged-in. [not-logged-in]
console.log("this.userId: " + this.userId) //is undefined
}
}
see https://docs.meteor.com/api/methods.html#DDPCommon-MethodInvocation-userId for more info on user id
test runner fails to import files in client directory
MochaRunner.runServerTests: failures: 1 when meteor methods are called
I have to call the server side meteor methods that have been declared in the testing context as if I am on the client, but I can't import the client files or operate as if I'm a client
MochaRunner.runServerTests: Starting server side tests with run id R7ocZh3Qva3rExTL9 runs basically every time
This seems useful but hasn't worked for me yet https://forums.meteor.com/t/testing-methods-which-use-this-userid/2292/8
Thank you for your help, any code examples would be great.
Remarks
I wanted to post a comment but do not have enough reputation. So here are some remarks. Since you are testing on the server, you can call a Meteor method without a callback. This will result in a synchronous execution and simplify your test. Otherwise you will have to let the test know it is finished by calling the done function in your callback, see mocha docs.
Using mdg:validated-method
You can call a valited method and provide the context in which they execute using the _execute function. Below is an example taken from the todos sample project. For more examples you can take a look at their Lists and Todos tests.
it('makes a list private and updates the todos', function() {
// Check initial state is public
assert.isFalse(Lists.findOne(listId).isPrivate());
// Set up method arguments and context
const methodInvocation = {
userId
};
const args = {
listId
};
// Making the list private adds userId to the todo
makePrivate._execute(methodInvocation, args);
assertListAndTodoArePrivate();
// Making the list public removes it
makePublic._execute(methodInvocation, args);
assert.isUndefined(Todos.findOne(todoId).userId);
assert.isTrue(Todos.findOne(todoId).editableBy(userId));
});
Using standard methods
Another possiblity would be to bind the standard call function to the correct context. Note that this is just a thought and not tested.
var methodInvocation = {
userId: "some user id"
};
Meteor.call.bind(methodInvocation)('createAgenda', mockAgenda);
I found it a little complicated, and more complicated if I wrote my meteor methods in /lib folder, that I want is to test from server test folder my methods (unit test), but stub this.userId and also debugging or showing logs in server side does not help too much.
I was having too much problems with it, I'm using mochajs with velocity, does anyone would help me please? is someone know how can I write the units to meteor methods?
Mocha doesn't support unit tests, only Jasmine does currently. This is an example of how you would write a unit test in Jasmine for the server and use userId.
it("should return premium content to logged in users", function () {
// SETUP
var thisContext = {
userId : true
};
var expectedCursor = 'chapter_cursor1';
var _query = true, _modifiers = true;
Chapters.find = function(query, modifiers) {
_query = query;
_modifiers = modifiers;
return expectedCursor;
};
// EXECUTE
var actualCursor = Meteor.publishFunctions['chapters'].apply(thisContext);
// VERIFY
expect(actualCursor).toBe(expectedCursor);
expect(_query).toBe(undefined);
expect(_modifiers).toBe(undefined);
});
Taken from here: https://github.com/xolvio/Letterpress/blob/master/tests/jasmine/server/unit/chaptersSpec.js#L3