It's tremendously helpful that there's a tool to generate mock versions of the client stubs. Testing the server side is causing me tons of headache at the moment. Enough headache where I feel like I must be doing something fundamentally wrong.
I may be misreading the following, but the end2end tests, including 'mock_test' seem to be using an actual client-server connection to drive testing. They may mock out the client, or mock out the client readers/writers to see the response from the server, but it's not clear to me how to test the server in isolation.
What I want to be able to do: I have some Service implentation that inherits from the gRPC generated class "Service." suppose that service exposes an interface ::grpc::Status Foo(::grpc::ServerContext* context, const CommandMessage* request, ::grpc::ServerWriter<CommandResponse>* writer); My gut for writing unit tests is saying to pass in a mock "ServerWriter" class and expect 'Write' is called when appropriate. But ServerWriter is marked final and can't be overridden.
This isn't the first place I've run into trouble with my kind of standard ways of mocking and gRPC's server stuff. The Server class, the ServerBuilder class, etc. I've wrapped so that I could put mock versions of them into tests (to validate that the correct parameters are being passed to my Server when it's being constructed, e.g.)
So I think I'm missing something with grpc then. I just don't know what. Am I supposed to stand up a real server in my unit tests and probe it with a mock client? How do I validate the proper server configurations are being passed, if I have to stand up a test version with test configurations? The code has interface classes and virtual methods, but then the parts that seem exposed for public use don't seem to be easily mockable as I'd expect.
As title, when to use httptest.Server and httptest.ResponseRecorder?
It seems to me that I can also test my handlers to return correct response using httptest.Server. I can simply start a httptest.Server given with my implementation of handlers, then do validations on the response's body.
Please correct if I'm wrong, I am learning Go + TDD
When you just want to check, if your http.Handler does what it should, you don't need to use httptest.Server. Just call your handler with an httptest.ResponseRecorder instance and check the output as in the example.
The possible uses of httptest.Server are numerous, so here are just a couple that come to my mind:
If your code depends on some external services and APIs, you can use a test server to emulate them. (Although I personally would isolate all code dealing with external data sources and then use them through interfaces, so that I could easily create fake objects for my tests.)
If you work on a client-server application, you can use a test server to emulate the server-side when testing the client-side.
I'm working on a fresh Grails project and recently noticed the default convention in the Spring Security Core generated User class now auto-encodes the password via a beforeInsert/Update event. That's a nice, clean, DRY way of doing the encode, and also makes it impossible to forget to do so.
However, now when trying to write up some unit tests which make use of said User class, I find I either have to mock out the springSecurityService (due to the encode), or more preferably (and cleanly), I'd just override the beforeInsert/Update closure with one that does nothing. Typically in Groovy one can override a method using the ExpandoMetaClass, ala...
User.metaClass.beforeInsert = { /* do nothing */ }
...but I'm finding that the original beforeInsert continues to be called upon creating and saving a new User. This in turn causes my unit tests to blow up. It's trivial for me to just work around this and mock out the service, but the above should work. Am I missing something? Is there something different with GORM's event closures that I'm not picking up on?
In order to improve performance Grails uses reflection directly with caches method handles for invoking events and not Groovy's meta layer. The reason is that if you are saving hundreds of domain instances it can seriously hurt performance if Grails had to go through Groovy's meta layer for each event.
There are ways around this such as defining your own User class that disables the event based on a system/environment property that your test sets etc. but there is currently no way to override the methods via meta programming.
The beforeInsert closure actually is not only a method like toString() or save(), but also it is a pre-defined event supported by Gorm. Override the method will not prevent Gorm from firing the PreInsert event, which leads to the original process.
If necessary, you can replace the code in the beforeInsert with a private method and then override the private method
I am learning unit testing and mocking. I have JUnit running, and instead of using a Mocking Framework, I have manually created mock classes by extending existing classes and interfaces. I would like to learn the mocking framework EasyMock because thats all thats available here at my work. While you might suggest some other mocking framework, they will not be available to me.
The Setup:
I have a View and a Presenter and a API backend. When the user clicks a button: "Check For Updates", the view calls the presenter.checkForUpdates() which does a call to api.checkForUpdates() and expects an callback. If the an exception occurs, the api will notify the presenter via a callback, and the controller will call the view method view.showUserError(). Callbacks are used not return parameters because of the async nature of hitting our API bac
kend.
The Object under test is the Presenter. Specifically, I want to test that the View.showUserError() gets called when an exception occurs in the Api. I believe I can mock Api.checkForUpdates() to immediately call the exception callback instead of doing an actual network call.
The problem is, I only see EasyMock mocking return values. For example:
EasyMock.expect(api.checkForUpdates()).andReturn(xxxx)
wont work for me, since api.checkForUpdates() does not return anything and instead does a callback. What I really want to do is something like:
EasyMock.expect(api.checkForUpdates()).andExecute(exceptionCallback(NetworkError));
But I don't see how to do that. Is there something that can do what I want or am I missing something basic?
Thanks
I think you can make a stub using ‘ Expect().andDelegateTo()’ API.
http://devlearnings.wordpress.com/2010/07/10/easymock-assert-arguments-of-method-call/
EasyMock is a good choice :-) Look at the documentation to get more information.
You can call do
andThrow(exceptionCallback(NetworkError) which might suit your needs.
If you need something more powerful, andAnswer will let you do anything you want to create the answer. andDelegateTo might also be a good choice but you will have to implement a class implementing the same interface as the mock. Which will probably be more complex than the two other options in your case.
I have some written a number of unit tests that test a wrapper around a FTP server API.
Both the unit tests and the FTP server are on the same machine.
The wrapper API gets deployed to our platform and are used in both remoting and web service scenarios. The wrapper API essentially takes XML messages to perform tasks such as adding/deleting/updating users, changing passwords, modifying permissions...that kinda thing.
In a unit test, say to add a user to a virtual domain, I create the XML message to send to the API. The API does it's work and returns a response with status information about whether the operation was successful or failed (error codes, validation failures etc).
To verify whether the API wrapper code really did do the right thing (if the response indicated success), I invoke the FTP server's COM API and query its store directly to see if, for example when creating a user account, the user account really did get created.
Does this smell bad?
Update 1: #Jeremy/Nick: The wrapper is the focus of the testing, the FTP server and its COM API are 3rd party products, presumably well tested and stable. The wrapper API has to parse the XML message and then invoke the FTP server's API. How would I verify, and this may be a silly case, that a particular property of the user account is set correctly by the wrapper. For example setting the wrong property or attribute of an FTP account due to a typo in the wrapper code. A good example being setting the upload and download speed limits, these may get transposed in the wrapper code.
Update 2: thanks all for the answers. To the folks who suggested using mocks, it had crossed my mind, but the light hasn't switched on there yet and I'm still struggling to get my head round how I would get my wrapper to work with a mock of the FTP server. Where would the mocks reside and do I pass an instance of said mocks to the wrapper API to use instead of calling the COM API? I'm aware of mocking but struggling to get my head round it, mostly because I find most of the examples and tutorials are so abstract and (I'm ashamed to say) verging on the incomprehensible.
You seem to be mixing unit & component testing concerns.
If you're unit-testing your wrapper, you should use a mock FTP server and don't involve the actual server. The plus side is, you can usually achieve 100% automation like this.
If you're component-testing the whole thing (the wrapper + FTP server working together), try to verify your results at the same level as your tests i.e. by means of your wrapper API. For example, if you issue a command to upload a file, next, issue a command to delete/download that file to make sure that the file was uploaded correctly. For more complex operations where it's not trivial to test the outcome, then consider resorting to the COM API "backdoor" you mentioned or perhaps involve some manual verification (do all of your tests need to be automated?).
To verify whether the API wrapper code really did do the right thing (if the response indicated success), I invoke the FTP server's COM API
Stop right there. You should be mocking the FTP server and the wrapper should operate against the mock.
If your test runs both the wrapper and the FTP server, you are not Unit Testing.
To test your wrapper with a mock object, you can do the following:
Write a COM object that has the same interface as the FTP server's COM API. This will be your mock object. You should be able to interchange the real FTP server and your mock object by passing the interface pointer of either to your wrapper by means of dependency injection.
Your mock object should implement hard-coded behaviour based on the methods called on its interface (which mimics FTP server API) and also based on the argument values used:
For example, if you have an UploadFile method you can blindly return a success result and perhaps store the file name that was passed in in an array of strings.
You could simulate an upload error when you encounter a file name with "error" in it.
You could simulate latency/timeout when you encounter a file name with "slow" in it.
Later on, the DownloadFile method could check the internal string array to see if a file with that name was already "uploaded".
The pseudo-code for some test cases would be:
//RealServer theRealServer;
//FtpServerIntf ftpServerIntf = theRealServer.getInterface();
// Let's test with our mock instead
MockServer myMockServer;
FtpServerIntf ftpServerIntf = myMockServer.getInterface();
FtpWrapper myWrapper(ftpServerIntf);
FtpResponse resp = myWrapper.uploadFile("Testing123");
assertEquals(FtpResponse::OK, resp);
resp = myWrapper.downloadFile("Testing123");
assertEquals(FtpResponse::OK, resp);
resp = myWrapper.downloadFile("Testing456");
assertEquals(FtpResponse::NOT_FOUND, resp);
resp = myWrapper.downloadFile("SimulateError");
assertEquals(FtpResponse::ERROR, resp);
I hope this helps...
I agree with Nick and Jeremy about not touching the API. I would look at mocking the API.
http://en.wikipedia.org/wiki/Mock_object
If it's .NET you can use:
Moq: http://code.google.com/p/moq/
And a bunch of other mocking libraries.
What are you testing the wrapper or the API. The API should work as is, so you don't need to test it I would think. Focus your testing efforts on the wrapper and pretend like the API doesn't exist, when I write a class that does file access I don't unit test the build in streamreader...I focus on my code.
I would say your API should be treated just like a database or a network connection when testing. Don't test it, it isn't under your control.
It doesn't sound like you're asking "Should I test the API?" — you're asking "Should I use the API to verify whether my wrapper is doing the right thing?"
I say yes. Your unit tests should assert that your wrapper passes along the information reported by the API. In the example you give, for instance, I don't know how you would avoid touching the API. So I don't think it smells bad.
The only time I can think of when it might make sense to dip into the lower level API to verify results if if the higher-level API is write-only. For example, if you can create a user using the high-level API, then there should be a high-level API to get the user accounts, too. Use that.
Other folks have suggested mocking the lower-level API. That's good, if you can do it. If the lower-level component is mocked, checking the mocks to make sure the right state is set should be okay.