All the examples of jest and jest-fetch-mock I have come across use functions that perform an API query and return a payload directly from the function call.
In my case, I have a different setup. I have a class that has a property called 'data'. In the class there is a method called "get" which pulls data using fetch API and stores it in the data property. When the method is called, it simply returns true or false based on promise resolve or reject.
I am trying to figure out how to write unit tests for this in this case. My function doesn't return the data fetched; only a boolean value.
So if I use jestSpyOn to mock the class method, how would I set the data property, and then retrieve the result?
In my code, I do something like this (NOT in testing, but in the actual app):
contactStore = new ContactListStore();
// 'all' is a sample param passed
contactStore.get('all').then(res => {
if(res){
...perform action
}
});
As you can see the res argument is only boolean, and if true, then contactStore.data will contain the information retrieved from the server.
So to run a unit test on it, I need to call a mock get, and set a mock data property.
Any ideas how this would be done?
In your mock method, you just need return true.
Related
I am a bit confused. Components, controllers, routes, helpers and whatsoever. I simply want to grab a value from a JSON file and calculate it with a value on Ember.Helper. Which way should i use, i cannot know anymore, brain burned. Would someone please help me to grab the "sell" part of the "market_name" which equals to "BTC_USDT" on "https://stocks.exchange/api2/prices" and put that into helper?
Edited:
In fact i try to do something like that.
import Ember from 'ember';
export function formatBTC(value) {
var url = 'https://stocks.exchange/api2/prices';
var btc_price = Ember.$.getJSON(url).then(function(data) {
for (var i=0; i <= data.length-1; i += 1)
{
if (data[i].market_name == "BTC_USDT")
{
return data[i].sell;
console.log(data[i].sell+' - i got the value properly');
}
}
});
console.log(btc_price+' - shows nothing, i cannot pass the var btc_price to here, why not');
calculation = value * btc_price; //some syntax may apply, maybe Number(value) or whatsoever, but i cannot have my variable btc_price returns here.
return calculation.toFixed(8);
}
export default Ember.Helper.helper(formatBTC);
And from the index.hbs
{{format-btc 0.001}}
Still couldnt find a proper solution. I get the data[i].sell as btc_price, but couldnt pass it through to return part... what am i missing? or what am i doing wrong?
The issue you're encountering is because the ajax request executes. Execution of the function continues and returns the value before the promise returns.
While technically, you could fix this and use async/await in your helper function, you'll run into another issue - Every time your helper is called, you'll make a new ajax request that will fetch the current price and calulate the value.
My recommendation is that instead of a helper, you use a combination of a model and a controller. Because you're currently overwhelmed with the framework, I'll actually make a second suggestion of using a service + component
I recommend a service or a model because you want to persist the data that you've fetched from the pricing source. If you don't, every instance of the helper/component will make a new request to fetch data.
Service
A service is kind of a session collection in ember. It only gets instantiated once, after that data will persist.
ember g service pricing
In the init block, set your default values and make your ajax request.
# services/pricing.js
btcPrice:null,
init() {
this._super(...arguments);
Ember.$.getJSON(...).then(val=>{
# get correct value from response
# The way you were getting the value in your example was incorrect - you're dealing with an array.
# filter through the array and get the correct value first
this.set('btcPrice',val.btcPrice);
})
}
Component
You can then inject the service into the component and use a consistent price.
ember g component format-btc
Modify the controller for the component to inject the service and calculate the new value.
#components/format-btc.js
pricing: Ember.inject.service('pricing')
convertedPrice: Ember.computed('pricing',function(){
return pricing.btcPrice*this.get('bitcoins')
})
The template for the component will simple return the converted price.
#templates/components/format-btc.js
{{convertedPrice}}
And you'll call the component, passing in bitcoins as an argument
{{format-btc bitcoints='1234'}}
All of this is pseudo-code, and is probably not functional. However, you should still be able to take the guidance and piece the information together to get the results you want.
I'm trying to fix this issue https://github.com/dotnet-security-guard/roslyn-security-guard/issues/60 Affected file is https://github.com/dotnet-security-guard/roslyn-security-guard/blob/master/RoslynSecurityGuard/Analyzers/CsrfTokenAnalyzer.cs
There is DiagnosticAnalyzer implemented and the logic in VisitMethods(SyntaxNodeAnalysisContext ctx) method is not correct for API method. So that I want to add such check to that method to exclude all the controller methods which return ViewResult instance as API method will not return a view.
Can you suggest me how can I traverse a C# (and VB) method body and find if a body contains any statement which returns ViewResult instance?
Call .DescendantNodes() on the method's node and filter for all return statements.
For each return statement you find, check whether .Expression (which may not exist)'s TypeSymbol (from the semantic model) is / is convertible to ViewResult.
To handle expression-bodied members, do the same check for ArrowExpressionClause.
I have a GET method for webAPI which returns say hundred Products list. What logic should one need to check to diagnose the test as pass or fail?
Should I check for count>0 or anything else?
Ideally I should not check for product count as it may change (count==100).
Check out these useful links on unit testing with async web requests:
https://codereview.stackexchange.com/questions/85321/unit-testing-http-requests
https://msdn.microsoft.com/en-us/library/hh404088.aspx
https://codeutopia.net/blog/2015/01/30/how-to-unit-test-nodejs-http-requests/
http://www.jeremyg.net/entry/unit-testing-a-fetch-api-service-in-aurelia
http://lazamar.github.io/testing-http-requests-with-jasmine/
Why should I mock HTTP requests inside unit tests?
Suppose your client component has a variable count that it initialized to 0. Then you fire some web request, and it responds with data like this:
{
response: 500
}
where response can have any whole number value. Then count gets set to the value of response.
The basic gist of this unit test would be to mock the actual calling to the server (instead of making the api call and return the response, just return a hardcoded object). Then assert that the "count" variable is as you would expect it to be from this predefined response. You can then set up multiple cases (ie multiple tests) for each possible type of response that can be returned. Good luck!
I need to find out the value passed into an indexer.
My code (c#) that I need to test is as follows:
string cacheKey = GetCacheKey(cacheKeyRequest);
string cachedValue = myCache[cacheKey] as string;
So, I need to be able to identify the value of the "cacheKey" that was passed into the indexer.
I have attempted this using a Mock of the cache object:
var cache = MockRepository.GenerateMock<WebDataCache>();
The idea being that after the code had executed, I would query the mock to identify the value that had been passed into the indexer:
var actualCacheKey = cache.GetArgumentsForCallsMadeOn(a => a["somevalue"], opt => opt.IgnoreArguments())[0][0].ToString();
This gives me a compilation error: Only assignment, call, increment, decrement, and new object expressions can be used as a statement.
I saw one suggestion to make this a function in the following way:
var actualCacheKey = cache.GetArgumentsForCallsMadeOn(a => a["somevalue"] = null, opt => opt.IgnoreArguments())[0][0].ToString();
This now compiles,but throws a run-time InvalidOperationException: No expectations were setup to be verified, ensure that the method call in the action is a virtual (C#) / overridable (VB.Net) method call.
Any suggestions? [Am using RhinoMocks.3.6.1]
Many thanks in advance
Griff
PS - I have previously posted this in http://groups.google.com/group/rhinomocks but after several days the view-count remains depressingly low.
The exception tells you exactly what is happening:
InvalidOperationException: No expectations were setup to be verified, ensure that the method call in the action is a virtual (C#) / overridable (VB.Net) method call.
Which means, in order for Rhino to properly work (or, in order for Castle to generate working proxies) your indexer has to be virtual. If you can't make it so, Rhino won't help you in this situation.
Once you make your indexer virtual, it is simple task:
var cache = MockRepository.GenerateMock<WebDataChache>();
cache.Expect(c => c["SomeKey"]).Returns("SomeValue");
// perform actual test
cache.VerifyAllExpectations();
This ensures that cache is accessed with ["SomeKey"]. If key value will be different, test will fail at VerifyAllExpectations line.
I am having a controller method which accepts FormCollection as a parameter.
the controller method then builds the model using UpdateModel(Model, new[] { P1, P2 });
I would like to unit test the above method. I am populating the formcollection with P1 and P2 values but the model is not build correctly when called from unit testing.
Has anyone faced similar issue?
The UpdateModel method looks in the Request object when populating the model and it completely ignores this FormCollection you are passing. So you will need to mock the request and add the values to this object. But thats lots of work that isn't worth the efforts and I would recommend you a better way: instead of using FormCollection as action parameter and then calling UpdateModel inside your action use a strongly typed action parameter:
public ActionResult Foo(SomeViewModel model)
{
// The model binder will automatically call UpdateModel and populate
// the model from the request so that you don't need to manually
// do all this stuff
...
}
and in the unit test simply pass the desired model when invoking the controller action.