Unit Testing with items that need to send headers
Well, your session manager is basically broken by design. To be able to test something, it must be possible to isolate it from side effects. Unfortunately, PHP is designed in such a way, that it encourages liberal use of global state (echo
, header
, exit
, session_start
etc. etc.).
The best thing you can do, is to isolate the side-effects in a component, that can be swapped at runtime. That way, your tests can use mocked objects, while the live code uses adapters, that have real side-effects. You'll find that this doesn't play well with singletons, which I presume you're using. So you'll have to use some other mechanism for getting shared objects distributed to your code. You can start with a static registry, but there are even better solutions if you don't mind a bit of learning.
If you can't do that, you always have the option of writing integration-tests. Eg. use the PHPUnit's equivalent of WebTestCase
.
How to setup Request.Header in FakeHttpContext for Unit Testing
I just discovered that with HttpRequestMessage class, you can easily add headers for testing your WebAPI controllers without having to create any fake HttpContext.
var request = new HttpRequestMessage(HttpMethod.Get, "http://stackoverflow");
request.Headers.Add("deviceId","1234");
_myController.Request = request;
Why does PHPUnit interfere with setting HTTP headers in this code?
The answer to your literal question "Why does PHPUnit interfere with setting HTTP headers in this code?" is given fairly clearly in the answer to Test PHP headers with PHPunit. PHP's header()
will fail with the Cannot modify header information
warning if anything has been written to stdout. When running your code via PHPUnit, content has been sent to stdout long before your code under test has been reached.
You noted a separate issue when using the @runInSeparateProcess
annotation to fork a clean PHP process for your test:
Unexpected non-MediaWiki exception encountered, of type "Exception", exception 'Exception' with message 'Serialization of 'Closure' is not allowed' in /usr/share/pear/PHPUnit/Util/GlobalState.php:354
By default PHPUnit attempts to backup all of the $GLOBALS
data before each test and restore it afterwards. MediaWikiTestCase turns this behavior off but it looks like your extension's tests are not. It seems likely that the configuration for your extension includes a closure and is causing the serialization failure. Adding a @backupGlobals disabled
annotation to your PHPUnit_Framework_TestCase
class should get you past this problem.
Unit test for a header created inside controller
Turned out that all what I needed was to indicate that the class was instance of Pagable.class. Here is the working test:
Page<Person> page = new PageImpl<>(new ArrayList<>());
when(pepleService.getPeopleSystems(any(Pageable.class))).thenReturn(page);
mockMvc.perform(get("/people")
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(header().string("CustomHeader1", "2000"));
How can I create a header response for unit tests?
Instead of mocking HttpRespone object calls i will recommend to create. HttpResponse
object with corresponding values
HttpResponse<String> httpResponse = new HttpResponse<String>() {
@Override
public int statusCode() {
return 200;
}
@Override
public HttpRequest request() {
return null;
}
@Override
public Optional<HttpResponse<String>> previousResponse() {
return Optional.empty();
}
@Override
public HttpHeaders headers() {
return HttpHeaders.of(Map.of("", List.of()), (v1,v2)->true);
}
@Override
public String body() {
return null;
}
@Override
public Optional<SSLSession> sslSession() {
return Optional.empty();
}
@Override
public URI uri() {
return null;
}
@Override
public HttpClient.Version version() {
return null;
}
};
Angular unit test HTTP request header
Is there other code in your spec that uses the spread operator?
See working example below please.
import { HttpClient, HttpClientModule, HttpHeaders, HttpRequest } from '@angular/common/http';
import {
HttpClientTestingModule,
HttpTestingController,
TestRequest,
} from '@angular/common/http/testing';
import { TestBed, waitForAsync } from '@angular/core/testing';
describe('headers test', () => {
let httpTestingController: HttpTestingController;
let httpClient: HttpClient;
beforeEach(
waitForAsync(() => {
void TestBed.configureTestingModule({
imports: [HttpClientTestingModule, HttpClientModule],
})
.compileComponents()
.then(() => {
httpTestingController = TestBed.inject(HttpTestingController);
httpClient = TestBed.inject(HttpClient);
});
}),
);
afterEach(() => {
httpTestingController
.match((req: HttpRequest<unknown>): boolean => true)
.forEach((req: TestRequest) => (!req.cancelled ? req.flush({}) : null));
httpTestingController.verify();
});
it('should have my header', () => {
const headers = new HttpHeaders().set('Custom-Header', 'test');
void httpClient.get('/someURL', { headers }).subscribe();
const req = httpTestingController.match('/someURL');
console.warn('req', req);
console.warn(req[0].request.headers);
expect(req[0].request.headers.has('Custom-Header')).toEqual(true);
});
});
How to test for expected headers?
If you have xdebug installed you can use xdebug_get_headers() to get the headers. Then you can test them as needed.
$headers=xdebug_get_headers();
gets you an array which looks like...
array(
0 => "Content-type: text/html",
1 => ...
)
So you'll need to parse each header line to separate the header name from the value
Related Topics
Sending Data Along with a Redirect in Codeigniter
Difference Between Require and Install VS Create-Project in Composer
Yii2 Require All Controller and Action to Login
How to Verify a Tls Smtp Certificate Is Valid in PHP
How to Send an Email Using PHP at Windows Azure
Unpacking an Array of Arguments in PHP
Check If Links Are Broken in PHP
Jquery UI Autocomplete with JSON and Ajax
Add Attachment Through PHPmailer
Interview Question: in PHP, Is 123==0123
Laravel Auth:Attempt() Will Not Persist Login
PHP & SQL Injection - Utf8 Poc
Does the Condition After && Always Get Evaluated
Does PHP's $_Request Method Have a Security Problem