views:

63

answers:

1

How do I refactor to remove the code duplication in this spec:

describe 'TestPlugins'
    describe '.MovieScanner(document)'
        before_each
            MoviePage_loggedIn = fixture("movie_logged_in.html")                // Get logged-in movie page
            MoviePage_notloggedIn = fixture("movie_not_logged_in.html")     // Get non logged-in movie page
            scanner = new MovieScanner()                                                // Get movie scanner
        end

        it 'should scan logged-in movie page for movie data'
            doc = MoviePage_loggedIn            // Get document to scan

            // Unit Tests
            // ------------------------------------------------------------

            // Test movie scanner's functions
            scanner.getMovieTitle(doc).should.eql "The Jacket"
            scanner.getMovieYear(doc).should.eql "2005"

            // Test movie scanner's main scan function
            scannedData = scanner.scan(doc)
            scannedData.title.should.eql "The Jacket"
            scannedData.year.should.eql "2005"
        end

        it 'should scan non logged-in movie page for movie data'
            doc = MoviePage_notloggedIn     // Get document to scan

            // Unit Tests
            // ------------------------------------------------------------

            // Test movie scanner's functions
            scanner.getMovieTitle(doc).should.eql "The Jacket"
            scanner.getMovieYear(doc).should.eql "2005"

            // Test movie scanner's main scan function
            scannedData = scanner.scan(doc)
            scannedData.title.should.eql "The Jacket"
            scannedData.year.should.eql "2005"
        end
    end
end
A: 

In BDD, we want to describe the behaviour of our app or classes to make them easy to change. If removing duplication would also obscure the behaviour, don't remove the duplication. The code gets read 10x more than it's written, and IME even more for BDD scenarios and unit-level examples.

If you do decide to remove the duplication anyway, replace it with something readable. I'm not familiar with JSpec but I'd expect something like

scannedData.shouldMatch "The Jacket", "2005"

where all the relevant outcomes for title and year are checked.

To remove the duplication irrelevant of whether you logged in or not:

Separate the code into Givens (context where it doesn't matter how you got there), Whens (events through the app whose behaviour you actually want to test) and Thens (outcomes you're looking for). You're looking to describe the capabilities of the system and things a user can do with it, rather than whether it's a web-page or a window - it shouldn't matter. Put the lower-level calls at a lower level.

You can then have two different givens - logged in or not logged in - and reuse the other steps for the rest.

Lunivore
Thanks for your answer! I had meant, how do I combine the tests for both the logged-in and non logged-in pages so that the same testing code isn't duplicated across the tests?
Chetan
Edited. Hope it helps!
Lunivore