I have never wrote a line of cfmodule myself. However, now is the time to refactor. What steps do you usually take to refactor cfmodule into cffunction / .cfc?
I'm thinking... refactor them into cffunctions (attributes becomes arguments), and return struct for multiple values, value for single value. Then group related functions into CFC's, and separate DB access into DAO/Gateway object. Unit test the hell of each of them.
Alternative, my colleague is thinking, maybe we should use a CFC for each 'flow' of cfmodules, and use obj's variables.instance scope as caller scope, then return the instance struct at the end of the 'flow'? Easier, but doesn't seem very testable.
Anyone has exp with refactoring cfmodule's?
Refactor your objects into CFC's as you're thinking.
Refactoring the application into divisions based off of the current procedural use is the wrong approach for sure. You basically hard coding your business logic to your value objects, which is a no no.
When it's time to add functionality with your existing codebase, you'll be glad you didn't group your logic in with your data. :)
Related
I'm writing a BDD unit test for a public method. The method changes a private property (private var) so I'd like to write an expect() and ensure it's being set correctly. Since it's private, I can't work out how access it from the unit test target.
For Objective-C, I'd just add an extension header. Are there any similar tricks in Swift? As a note, the property has a didSet() with some code as well.
(Note that Swift 2 adds the #testable attribute which can make internal methods and properties available for testing. See #JeremyP's comments below for some more information.)
No. In Swift, private is private. The compiler can use this fact to optimize, so depending on how you use that property, it is legal for the compiler to have removed it, inlined it, or done any other thing that would give the correct behavior based on the code actually in that file. (Whether the optimizer is actually that smart today or not, it's allowed to be.)
Now of course if you declare your class to be #objc, then you can break those optimizations, and you can go poking around with ObjC to read it. And there are bizarre workarounds that can let you use Swift to call arbitrary #objc exposed methods (like a zero-timeout NSTimer). But don't do that.
This is a classic testing problem, and the classic testing answer is don't test this way. Don't test internal state. If it is literally impossible to tell from the outside that something has happened, then there is nothing to test. Redesign the object so that it is testable across its public interface. And usually that means composition and mocks.
Probably the most common version of this problem is caching. It's very hard to test that something is actually cached, since the only difference may be that it is retrieved faster. But it's still testable. Move the caching functionality into another object, and let your object-under-test accept a custom caching object. Then you can pass a mock that records whether the right cache calls were made (or networking calls, or database calls, or whatever the internal state holds).
Basically the answer is: redesign so that it's easier to test.
OK, but you really, really, really need it... how to do it? OK, it is possible without breaking the world.
Create a function inside the file to be tested that exposes the thing you want. Not a method. Just a free function. Then you can put that helper function in an #if TEST, and set TEST in your testing configuration. Ideally I'd make the function actually test the thing you care about rather than exposing the variable (and in that case, maybe you can let the function be internal or even public). But either way.
In my unit tests, should I test for attributes on the models?
If I have a model called person, should write a test to make sure that person.name exists, and is required?
Since you did not specify a language I will have to answer generally.
If you have a dynamic language then it is pretty important to ensure that your dynamically generated objects contain all the fields required (and those fields are also populated appropriately.)
As a general rule when writing unit tests simply just write the test, what damage will it do? find a bug?, let someone know that they have broken something which might cause a bug?
It is always difficult to know when testing goes too far - i.e. if you have a method/property on an object that just returns the value found in an attribute, should we bother with tests that are so simple? Our strive for perfection tells us yes, but pragmatically it's not so simple, as you can end up with lots of extra tests that don't add a lot of value.
Constructors have always had a similar problem - if a constructor just takes parameters and saves them as attributes in the object, should we test this?
The approach I take here is for each class to add a test called test_construction to the unit tests for that class. This will construct an object, and then check the values for all of the methods/properties that look up these values. This gives test coverage for both the constructor and the attribute lookups, with minimal overhead of a single test.
However - if you or your team decides not to test these functions I would not worry too much either - any issues are likely to get picked up by other tests, and there are bound to be more important tests for you to write than these.
I'm new to test driven development and first time I'm tring to use it in a simple project.
I have a class, and I need to test creation, insertion and deletion of objects of this class. If I write three seperate test functions I need to duplicate initialization codes in other function. On the hand if I put all tests in one test function then it is a contradiction with one test per function. What should I do?
Here the situation:
tst_create()
{
createHead(head);
createBody(body);
createFoot(foot);
}
tst_insert()
{
createHead(head);
createBody(body);
createFoot(foot);
obj_id=insert(obj); //Also I need to delete obj_id somehow in order to preserve old state
}
tst_delete()
{
createHead(head);
createBody(body);
createFoot(foot);
obj_id=insert(obj);
delete(obj_id);
}
vs
tstCreateInsertDelete()
{
createHead(head);
createBody(body);
createFoot(foot);
obj_id=insert(obj);
delete(obj_id);
}
Rather than "One test per function", try thinking about it as, "One aspect of behaviour per function".
What does inserting an object give you? How about deleting an object? Why are these valuable? How can you tell you've done them? Write an example of how the code might be used, and why that behaviour is valuable. That then becomes your test.
When you've worked out what the behaviour is that you're interested in, extract out the duplication only if it makes the test more readable. TDD isn't just about testing; it's also about providing documentation, and helping you think about the responsibility of each element of code and the design of that code. The tests will probably be read far more than they're written, so readability has to come first.
If necessary, put all the behaviour you're interested in in one method, and just make sure it's readable. You can add comments if required.
Factor out the duplication in your tests.
Depending on your test framework, there may be support for defining a setup method that's called before each test execution and a teardown method that's called after each test.
Regardless, you can extract the common stuff so that you only have to repeat a call to a single shared setup.
If you tell us what language and test framework you use, we might be able to give more specific advice.
So, I'm starting to write some logic for a simple program (toy game on the side). You have a specific ship (called a setup) that is a ship + modules. You start with an empty setup based off a ship and then add modules to that setup. Ships also have a numbered array of module positions.
var setup = new Setup(ship); // ship is a stub (IShip) defined someplace else
var module = new Mock<IModule>().Object;
setup.AddModule(module, 1); // 1 = which position
So, this is the code in my test method. I now need to assert on this code. Well, I need a getter method right?
Assert.AreEqual(module, setup.GetModule(1));
This might sound really dumb and I'm worrying about nothing, but for some stupid reason I'm concerned with adding a method just to assert that a test passed.
Is this fine and is in fact part of the design process that TDD is pushing out? For instance I know I need an AddModule method because I want to test it, and the fact that this requires a GetModule method to test is simply an evolution of my design via TDD.
Or is this kind of a smell because I don't even know if I'll really need GetModule in my code and it will only be used in a test?
For example, adding a module is going to ultimately affect different stats of a setup (armor, shield, firepower, etc). The thing is those are going to be complex, and I wanted to start with a simple test. But in the end, those are the public attributes I care about -- a setup is defined by its stats, not by a list of modules.
Interesting question. I'm glad to hear you're writing the tests first.
If you let the design manifest itself through the tests, you're more likely to build only the parts you'll need. But is this the best design? Maybe not, but don't let that discourage you -- your add method works!
It may be too early to tell if you'll need the GetModule method later. For now, build up the functionality you need and go green, then slowly refactor it (going from red to green again) to get the design you want.
Part of evolving the design is to start with baby steps like a simple method and then grow into the complex stats (eventually dropping this method and changing the test) when enough supports it. When doing TDD, don't expect that the first test you write is targeting the ideal interface. It is OK to have some messiness that will get dropped as you evolve the design.
That being said, if you see no public purpose to the method, try to limit its visibility as much as is reasonable to the test code. Although even that should eventually go away as you get to build out the rest of the system and have something real to test as a side effect of the set method.
I would be wary of introducing a public method in my class that is only used for testing.
There are various ways how you could test this:
Reflection: The GetModule method is a private method in your class (this could also work if your 'stats' are private) and you can access it in your test method via reflection. This will work well, the only trouble is you will not get any compiler errors if you change the name of the private method or add / delete some variables (but, of course, your test will fail and you will know early)
Inheritance: The GetModule method could be protected (only inheritance visible) and your test class could inherit from the main class. This way your test class gets access to this method, but this is not really exposed to the outside world.
Assert the side-effect: This is where you really think about what it means to add a module to the system. If it is going to affect some 'stats' as you put it, you could write tests which assert that the stats are appropriately modified.
I am in the process of learning to unit test. I have a 'domain object' that doesn't do much apart from hold state (i.e. Employee without any business logic). It has a method SetDefaults() which just fills its state with reasonable values. A simple method.
But when I go to unit test this method all I can think of is to run the method then check that every field is what it should be. Like (in C#):
[TestMethod()]
public void SetDefaultsTest()
{
Employee target = new Employee();
employee.SetDefaults();
Assert.AreEqual(employee.Name, "New Employee");
Assert.AreEqual(employee.Age, 30);
// etc.
}
It feels wrong to duplicate the entire functionality of SetDefaults() within my test. Should I just leave this method untested? The problem is that I'd like a test to ensure that when new properties are added to the class they are also added to the SetDefaults() method.
Trivial getters and setters sometimes don't have unit tests written for them. If that's all that SetDefaults() does, it probably won't hurt to skip it.
One thing you would want to consider testing, though, is that none of the set properties of the employee instance are null after calling SetDefaults():
var nonNullProperties = new object[] { employee.Name, employee.Age, ... };
foreach (var property in nonNullProperties)
Assert.IsNotNull(property);
This makes sense, since you really just care that they are set to some default value, and not so much that they're a specific value.
It depends on what value you get out of that test. Don't test just for the sake of testing. However, if those defaults are important to be correct, and not change, then go right ahead.
A lot of testing involves deciding "Hey, is this going to make my job easier in the long run?" Are these defaults changing all the time, or are they constant? Are the defaults very complicated, or are they a handful of strings and numbers? How important is it to the customer that these defaults are correct? How important is it to the other developers that the defaults are correct?
The test could do a million things, but if it doesn't add some value to someone who cares about it, then don't worry about it. If you've been asked to automate testing of 100% of all your code, perhaps reading up and discussing some of the ideas presented in the following blogs might benefit your team:
http://blog.jayfields.com/2009/02/thoughts-on-developer-testing.html
http://msdn.microsoft.com/en-us/magazine/cc163665.aspx
Otherwise, if it doesn't add much value or constantly breaks, I'd say go ahead and leave it out.
That looks like a pretty reasonable unit test to me. You are providing a simple test that checks the results of calling that method. It doesn't help you with any new properties though, as the existing test would still pass. Perhaps you could use Reflection to iterate over all the properties of the object and check they are non-null?
Also SetDefaults() seems like a slightly odd method. Why not just initialise a new Employee to those values to start with? That way there is no risk that another coder will create an Employee and forget to call SetDefaults().