I'd like to unit test some controller actions and ultimately test that validation attributes and action response filters are functioning properly. To do this sort of thing in ASP .NET MVC was easy with mvccontrib; however, with Web API, mocking the HttpContext seems to be quite a bit different.
How do I go about mocking HttpContext for a Web API controller so that I can test model binding and the like?
You shouldn't need HttpContext in a Web API. Everything you need should be in the HttpRequestMessage and its Properties collection.
Do not use HttpContext.
Just Mock the service and the controller and go with somthing like this:
_serviceMock.Setup(s => s.YourFunction(params if needed)).Returns(return value).
var response = _controllerMock.YourFunction(parameter);
_serviceMock.VerifyAll();
var result = response.Result;
var value = result.Value;
Related
I'm implementing a web-scraping script for a website which will collect some useful information.
Script is implemented using Puppeteer library and is basically a set of instructions like:
Start a headless chrome
Open new tab/page
Get some pagination links from the HTML
Open every pagination link found and scrape some information from HTML
I'm looking for some way of testing this functionality. Ideally, what I want to do is to "pre-save" the real HTML responses in test folder and then mock the external website responses (making sure they always are the same). And then assert that collected information is correct.
I'm familiar with several tools which are able to mock endpoints for fetch function in the browser. I'm looking for something similar but for Puppeteer.
So far, the only solution I'm thinking about is to use browser instance as a dependency for my script. And then mock the newPage method of the browser to return a page with custom interceptor. This looks like a lot of work though.
Any other solution for this?
A simple solution is to store the HTML page you want to test (or parts of it) locally and open it in Puppeteer. It is possible to open local HTML websites in Puppeteer. Then the result can be tested in a Javascript test framework like Mocha or Jest.
If you need a real web server for the tests, another option is to use a library like Express to serve local HTML pages as a mock for a web server response. You can find an example in this search engine scraper which contains tests for scraping various search engines.
It is also possible to mock and stub Puppeteer functions like launch, goto and $eval. This approach requires a lot of stubbed methods.
This is something I am playing around with at the moment.
I got this working by setting setRequestInterception:
it('responds', () => {
return (async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setRequestInterception(true);
page.on('request', request => {
// TODO: match request.url()
request.respond({
content: 'application/json',
headers: {"Access-Control-Allow-Origin": "*"},
body: JSON.stringify({foo: 'bar'})
})
});
res = await page.goto('https://example.com');
json = await res.json()
await browser.close();
expect(json).toStrictEqual({"foo": "bar"})
})();
})
This also looks to be a useful tool: https://github.com/jefflau/jest-fetch-mock. Maybe it could be handy to match requests etc
Also see: Best way to intercept XHR request on page with Puppeteer and return mock response
I am trying to develop a PATCH endpoint in my web api application. In the update model I have attributes for required data and some custom attributes. Since I found out that the attribute validation is not executed as expected in PATCH endpoints I needed to trigger the validation with a method as follows
private void Validate(object model, Type type)
{
var validator = Configuration.Services.GetBodyModelValidator();
var metadataProvider = Configuration.Services.GetModelMetadataProvider();
HttpActionContext actionContext = new HttpActionContext(
ControllerContext, Request.GetActionDescriptor());
if (!validator.Validate(model, type, metadataProvider, actionContext, String.Empty))
{
throw new HttpResponseException(Request.CreateErrorResponse(
HttpStatusCode.BadRequest, actionContext.ModelState));
}
}
This logic works fine for me. The problem is that when I try to write a unit test for the PATCH endpoint the tests fails because Request.GetActionDescriptor() returns null. Maybe I need to set up my controller in a different way. Any ideas? Maybe I need to setup the Request object somehow
I want to test my models, and their integration with my REST API, using the Ember testing framework which ships with Ember CLI, but requests, using my RESTAdapter settings are not being made in my tests, within my model tests. As it stands, any call to save() on a model will cause all tests following it to not execute:
Here is a test I made to check interaction with the server (REST API):
test "store can be used to send data to server", ->
store = #store()
Ember.run ->
cpanel = store.createRecord "item"
cpanel.save().then((response) =>
equal(response.status, 200)
)
This completely blocks all tests following this one; furthermore, no requests are made to the server, when monitoring the Network tab in Chrome dev tools:
A friend advised me to use the QUnit Async Helper, but when using that, I find that this.store() is undefined (perhaps the Ember QUnit Adapter decided to leave out support for async testing helpers?):
asyncTest "Async creates account on server", ->
expect(2)
store = #store()
Ember.run =>
account = store.createRecord("account", {
siteName: "sample account"
url: "http://url.com"
})
account.save().then((response) =>
equal(response.status, 200)
ok account
start()
)
How can I write an async test for my individual models, and test their integration with my REST API using the Ember QUnit framework in Ember CLI without having to write integration tests?
I'm not sure where status is coming from, the promise of save returns the record, not the response from server.
In order to use start, you must use stop first.
stop();
someAsyncCall(function(){
start();
});
And the store is only injected into routes and controllers, and isn't in scope of your tests. You'll need to use the container to get the store.
store = App.__container__.lookup('store:main');
It'd look something like this:
test("save a record", function(){
var record,
store = App.__container__.lookup('store:main');
stop();
Em.run(function(){
record = store.createRecord('color', {color:'green'});
record.save().then(function(){
start();
equal(record.get('id'), 1);
});
});
});
Example: http://emberjs.jsbin.com/wipo/49/edit
I'm writing some functional tests in play, however I want to test my stack isolated from other http endpoints.
Is there a mechanism for me to say "Direct WS calls to this set of canned responses" or some other way of stubbing out calls to http endpoints that won't be available for automated tests?
Alternatively, how does fakeApplication config get presented to the rest of the application so I can just set the URL to some localhost server which I'll build myself to provide canned responses
You could create a structural type that mimics the WS signature and use that in your code.
type WSLike = {
def url(url: String): WSRequestHolder
}
Then you can inject your own version of a WSLike class. In combination with a mock library I guess you could do about anything you want.
As for the second question. You could call it like this:
val url = Play.current.configuration
.getString("my.webservice.url")
.getOrElse(throw new PlayException(
"Configuration error",
"Could not find my.webservice.url in settings"))
WS.url(url)
Then in your application.conf add the correct url. You can supply a different one using the FakeApplication.
FakeApplication(additionalConfiguration =
Map("my.webservice.url" -> "http://localhost/service"))
I am working on a Restful Web Service, which get request from client, then strip some information and insert it into the database.
When it insert to the database, it has two parts of information needed: Uri and HttpRequest.
Now I have my method like this:
public void insertDb (#Context UriInfo uriInfo, #Context HttpServletRequest request)
I am trying to do some unit testing, create a client then WebResouce.
I wonder how can I pass in the parameters in unit testing? Or should I change the params in the insertDb function?
Have you heard about Jersey Test Framework? http://jersey.java.net/nonav/documentation/latest/test-framework.html
You don't need to change signature of your method, you need to start Jersey somehow (Test Framework can help you with that) and make request to that Resource. Simple sample of this can be seen in helloworld sample, see http://search.maven.org/remotecontent?filepath=com/sun/jersey/samples/helloworld/1.10/helloworld-1.10-project.zip.