I've been out of touch with TDD for some time, and am very rusty. I'd appreciate some suggestions on how to TDD the method described below.
The method must find a web.config file in a user supplied application directory. It must then extract and return a connection string from that config file.
It returns null if for any reason the connection string isn't found, be it a bad path, no web.config, or no connection string in web.config.
My initial thoughts are to write a test with setup that creates a directory and writes a web.config file with a connection string. The test would then call my method with the created path and expect a non-null value back, and my initial test run would fail because my method stub always returns null.
Then, implement the method, and run the test expecting a pass. Then, as a pre-test (I forget the term), delete the created directory, and call the method expecting a null value.
First, I wouldn't have the method both find the file and extract the connection string. If your framework doesn't already have a method to determine if a file exists in a given directory, write a method to do then, once you have a file, write a method to extract the connection string from an open stream. For testing, then, you could supply a memory stream instead of having to actually create a directory and file.
Second, if you aren't depending on a failed compile being your first failing test, then write your first attempt at the method to throw a NotImplementedException. It's a small step, but when you write your first test, at least it will fail. Of course, the first test on an empty stream will expect it to return null and the first code you write will be return null, but that's ok. Your next test will force you to change it. Continue on from there until you've got your completed methods.
You appear to have several TestCases with several distinct setUp fixtures.
The FoundDirectory TestCase. The setUp creates the expected, valid file.
This can have several subclasses.
A connection string not found TestCase. The setUp creates the expected, but invalid file.
A bad path TestCase. The setUp creates the expected, but invalid file.
A no web.config TestCase. The setUp creates the expected, but invalid file.
A no connection string in web.config TestCase. The setUp creates the expected, but invalid file.
The DidntFindDirectory TestCase. The setUp assures that the directory doesn't exist.
The DidntFindFile TestCase. The setUp creates the directory but no file.
Make the object that hold you method (or the method itself) dependent on a IConfigLoader of some sort, that you would be able to mock :
public interface IConfigLoader
{
XmlReader LoadAppConfigFrom(string path);
}
Use it from your method to get the XML file you want to parse.
I suggest that the story in your question mixes several issues:
finding and opening a file,
loading data into a "configuration" (however represented)
attempting to get a specific parameter from a "configuration"
Point 3 is now a matter of how a Configuration behaves, and can be developed in TDD fashion.
Point 2 is now a matter of how a Configuration is constructed (e.g by a ConfigurationLoader), and can be developed in TDD fashion (e.g. against a StringReader).
Point 1 is now a matter of whether you can open a Reader for a specified file path. It is easy to add after completing point 2.
Related
I have a QAudioRecorder object, the audio recording is successful, but the recordings are saved in the default directory, how can I specify my location to store the recordings? Used QAudioRecorder::setOutputLocation() unsuccessfully.
the QAudioRecorder class inherits the QMediaRecorder, this class has a property for this feature under the name "outputLocation" and with the Access functions:
QUrl outputLocation() const
bool setOutputLocation(const QUrl &location)
you can achieve that... here more info: https://doc.qt.io/qt-5/qmediarecorder.html#outputLocation-prop
According to the docs, setOutPutLocation():
Sets the output location and returns if this operation is successful.
If file at the output location already exists, it should be
overwritten.
The location can be relative or empty; in this case the service should
use the system specific place and file naming scheme.
After recording has started, the backend should report the actual file
location with actualLocationChanged() signal.
To make sure that your method-call works you can look at the return value when you call it. Or you can call this method: https://doc.qt.io/qt-5/qmediarecordercontrol.html#outputLocation which will:
Returns the current output location being used.
If setOutPutLocation() is successful outputLocation() should return the same value.
I'm trying to do a project described also here: PacketQueue is 0
I've modified the UdpBasicApp.cc to suit my needs, and in the handleMessage() function I added a piece of code to retrieve the length of the ethernet queue of a router. However the value returned is always 0.
My .ned file regarding the queue of routers is this:
**.router*.eth[*].mac.queue.typename = "DropTailQueue"
**.router*.eth[*].mac.queue.packetCapacity = 51
The code added in the UdpBasicApp.cc file is this:
cModule *mod = getModuleByPath("router3.eth[*].mac.queue.");
queueing::PacketQueue *queue = check_and_cast<queueing::PacketQueue*>(mod);
int c = queue->getNumPackets();
So my question is this: is this the right way to create a queue in a router linked to other nodes with an ethernet link?
My doubt is that maybe packets don't pass through the specified interface, i.e. I've set the ini parameters for the wrong queue.
You are not creating that queue. It was already instantiated by the OMNeT++ kernel. You are just getting a reference to an already existing module with the getModuleByPath() call.
The router3.eth[*].mac.queue. module path is rather suspicious in that call. It is hard-coded in all of your application to get the queue length from router3 even if the app is installed in router1. i.e. you are trying to look at the queue length in a completely different node. Then, the eth[*] is wrong. As a router obviously contains more than one ethernet interface (otherwise it would not be a router), you must explicitly specify which interface you want to sepcify. You must not specify patterns in module path (i.e. eth[0] or something like that, with an exact index must be specified). And at this point, you have to answer the question which ethernet interface I'm interested in, and specify that index. Finally the . end the end is also invalid, so I believe, your code never executes, otherwise the check_and_cast part would have raised an error already.
If you wanted to reach the first enthern interface from an UDP app in the same node, you would use relative path, something like this: ^.eth[0].mac.queue
Finally, if you are unsure whether your model works correctly, why not start the model with Qtenv, and check whether the given module receives any packet? Like,, drill down in the model until the given queue is opened as a simple module (i.e. you see the empty inside of the queue module) and then tap the run/fast run until next event in this module. If the simulation does not stop, then that module indeed did not received any packets and your configuration is wrong.
I have a application with a Django backend and an AngularJS front-end.
I use the angular-gettext plugin along with Grunt to handle translations.
The thing is, I sometimes received dynamic strings from my backend through the API. For instance a MySQL error about a foreign key constraint or duplicate key entry.
How can I add this strings to the .pot file or non harcoded string in general ?
I've tried to following but of course it cannot work :
angular.module('app').factory('HttpInterceptor', ['$q', '$injector', '$rootScope', '$cookieStore', 'gettext', function ($q, $injector, $rootScope, $cookieStore, gettext) {
responseError: function (rejection) {
gettext('static string'); //it works
gettext(rejection.data.error); //does not work
$rootScope.$emit('errorModal', rejection.data);
}
// Return the promise rejection.
return $q.reject(rejection);
}
};
}]);
})();
One solution I could think of would be to write every dynamic strings into a JSON object. Send this json to server and from there, write a static file containing these strings so gettext can extract them.
What do you suggest ?
I also use angular-gettext and have strings returned from the server that need to be translated. We did not like the idea of having a separate translation system for those messages so we send them over in the default language like normal.
To allow this to work we did two things. We created a function in our backend which we can call to retrieve all the possible strings to translate. In our case it's mainly static data that only changes once in a while. Ideally this would be automated but it's fine for now.
That list is formatted properly through code into html with the translate tag. This file is not deployed, it is just there to allow the extraction task to find the strings.
Secondly we created a filter to do the translation on the interpolated value, so instead of translating {{foo}} it will translate the word bar if that's was the value of foo. We called this postTranslate and it's a simple:
angular
.module('app')
.filter('postTranslate', ['gettextCatalog', function (gettextCatalog) {
return function (s) {
return gettextCatalog.getString(s);
};
}]);
As for things that are not in the database we have another file for those where we manually put them in. So your error messages may go here.
If errors are all you are worried about though, you may rather consider not showing all the error messages directly and instead determine what user friendly error message to show. That user friendly error message is in the front end and therefore circumvents all of this other headache :)
I am writing my first ApprovalTest. I need to understand why I am getting the following error when bothg my files are the same.
move /Y "C:\SampleMvc-master\SampleMvc-master\SampleMvc.Tests\Controllers\GoldenMasterTest.About.received.html" "C:\SampleMvc-master\SampleMvc-master\SampleMvc.Tests\Controllers\GoldenMasterTest.About.approved.html"
move /Y "C:\SampleMvc-master\SampleMvc-master\SampleMvc.Tests\Controllers\GoldenMasterTest.About.received.html" "C:\SampleMvc-master\SampleMvc-master\SampleMvc.Tests\Controllers\GoldenMasterTest.About.approved.html"
Test method SampleMvc.Tests.Controllers.GoldenMasterTest.About threw exception:
ApprovalTests.Core.Exceptions.ApprovalMismatchException: Failed Approval: Received file C:\SampleMvc-master\SampleMvc-master\SampleMvc.Tests\Controllers\GoldenMasterTest.About.received.html does not match approved file C:\SampleMvc-master\SampleMvc-master\SampleMvc.Tests\Controllers\GoldenMasterTest.About.approved.html.
My Code is
[TestMethod]
public void About()
{
//AspApprovals.VerifyUrl("http://localhost:50011/Home/About");
MvcApprovals.VerifyMvcPage(new HomeController().About);
}
ApprovalTests uses a "golden master" style of verification. Meaning that you will always fail the 1st time you run. Once it fails, but produces the right result, you will move the file over and then it will pass and continue to pass until something changes.
There are multiple ways to create the golden master, but one easy way in via the command line, which is why you are seeing the
move /Y "C:\SampleMvc-master\SampleMvc-master\SampleMvc.Tests\Controllers\GoldenMasterTest.About.received.html" "C:\SampleMvc-master\SampleMvc-master\SampleMvc.Tests\Controllers\GoldenMasterTest.About.approved.html"
this creates the .approved files from the .received file.
You might also want to check out this video on reporters which will help explore other ways to create the golden master and view the generated results:
Reporter video
or this video, about verifying MVC pages
MVC Approvals Video
Happy Testing!
I'm coding a long-running, multi-threaded server in C++. It receives requests on a socket, does database lookups and returns responses on a socket.
The server reads various run information from a configuration file, including database connectivity parameters. I have to use a database abstraction class from the company's code library. I don't want to wait until trying to do the DB search to lazy instantiate the DB connection (due to not shown complexity and the need for error exit at startup if DB connection cannot be made).
My problem is how to get the database connection information down into the search class without doing any number of "ugly" or bad OOP things that would technically work. I want to learn how to do this right way.
Is there a good design pattern for doing this? Should I be using the "Parameterize from Above" pattern? Am I missing some simpler Composition pattern?
// Read config file.
// Open DB connection using config values.
Server::process_request(string request, string response) {
try {
Process process(request);
if (process.do_parse(response)) {
return REQ_OK;
} else {
// handle error
}
} catch (..,) {
// handle exceptions
}
}
class Process : public GenericRequest {
public:
Process(string *input) : generic_process(input) {};
bool do_parse(string &output);
}
bool Process::do_parse(string &output) {
// Parse the input request.
Search search; // database search object
search.init( search parameters from parsing above );
output = format_response(search.get_results());
}
class Search {
// must use the Database library connection handle.
}
How do I get the DB connection from the Server class at top into the Search class instance at the bottom of the pseudo-code above?
It seems that the problem you are trying to solve is one of objects dependency, and is well solved using dependency injection.
Your class Process requires an instance of Search, which must be configured somehow. Instead of having instances of Process allocating their own Search instance, it would be easier to have them receive a ready made one at construction time. The Process class won't have to know about the Search configuration details, and thus an unecessary dependency is avoided.
But then the problem cascades up to whichever object must create a Process, because now this one has to know that configuration detail! In your situation, it is not really a problem, since the Server class is the one creating Process instances, and it happens to know the configuration details for Search.
However, a better solution is to implement a specialized class - for instance DBService, which will encapsulate the DB details acquired from the configuration step, and provide a method to get ready made Search instances. With this setup, no other objects will depend on the Search class for its construction and configuration. As an added benefit, you can easily implement and inject a DBService mockup object which will help you build test cases.
class DBSearch {
/* implement/extends the Search interface/class wrt DB */
};
class DBService {
/* constructor reads up configuration details somehow: command line, file */
Search *newSearch(){
return new DBSearch(config); // search object specialized on db
}
};
The code above somewhat illustrates the solution. Note that the newSearch method is not constrained to build only a Search instance, but may build any object specializing that class (as for example the class DBSearch above). The dependency is there almost removed from Process, which now only needs to know about the interface of Search it really manipulates.
The central element of good OOP design highlighted here is reducing coupling between objects to reduce the amount of work needed when modifying or enhancing parts of the application,
Please look up for dependency injection on SO for more information on that OOP design pattern.