0

I am trying to incorporate BDD into the teams working practices to make interactions with Business Analysts more effective. I recently asked this question: Should I pass an ID number from the feature file?

Please see the code below:

public class Chestnut
{
    private Guid _id;

    public Customer (Guid id)
    {
       if (id == Guid.Empty)
                throw new ArgumentException();           
         _id = id;
    }
    //Chestnut methods go here.
}

How would I test this class if I was using Specflow (like in my other question)? I was thinking about creating two tests:

1) A Chestnut is created because a valid ID is passed. 2) A Chestnut is not created because an empty ID is passed.

I was thinking about doing the following:

1) Given an ID; Then create a Chestnut with a valid state

2) Given an empty ID Then a validation error is presented for ID

Note that I am not specifying the ID in the actual scenario - because it is an implementation detail.

Is this a "good" test or is there another way of approaching this? Should I even be creating a test for this?

w0051977
  • 7,031
  • 6
  • 59
  • 87

2 Answers2

1

That constructor has behaviour, so testing it might be sensible. In particular: why is this code being written if not to make a test pass?

A test that just checks that an object was created is an extremely weak test. What useful properties does this exercise? Close to none, because other parts of the code that have to create a Chestnut will have to run that constructor anyway.

The test that construction should fail for empty IDs is more valuable, but this raises the question what the business value of this check is and why an ID can even be empty. If you can answer that (and give this test scenario a sensible name) then great, but otherwise test it anyway.

Note that these tests on levels of “constructors” and “IDs” are probably super low level implementation details, and don't encode any useful behaviour. Which business-level requirements are addressed by this behaviour? For such low-level details, a Gherkin-style scenario likely requires inappropriate amounts of effort. Those BDD-style tests should usually focus on higher-level behaviour and requirements. If you test this (and you should!) then a simpler unit testing framework will be much more appropriate.

amon
  • 132,749
  • 27
  • 279
  • 375
  • Thanks. Are you saying use Specflow for some tests and not others? – w0051977 Mar 04 '18 at 10:30
  • Yes. Different tests have different goals. BDD tools are inappropriate for low-level unit tests. – amon Mar 04 '18 at 12:04
  • Thanks. One more thing before I accept your answer. Say I am testing a Person class that has high level (Specflow) and low level tests. Would you create two separate test classes (one for high level and one for low level) or one test class for both. – w0051977 Mar 04 '18 at 12:32
  • I am not sufficiently familiar with Specflow to answer that question. Use your judgement. My initial instinct would be to separate from BDD-style application-level tests from TDD-style unit tests. – amon Mar 04 '18 at 12:48
  • Would you use the same naming conventions for methods in BDD and TDD i.e. ShouldDoSomething? It is often recommended to use different naming conventions in TDD. I am trying to follow the principle of least astonishment. – w0051977 Mar 04 '18 at 21:07
  • Are you able to answer my question in the comment above? Then I will mark the answer. – w0051977 Mar 05 '18 at 17:59
0

Testing a constructor with behavior makes sense. If something is public and can be tested explicitly it should be tested explicitly.

I have to disagree with Amon, you don't want to test the constructor implicitly with other tests. My understanding is that you specifically don't want to test anything the component you are testing is depending on explicitly. Keyword "test isolation". (Not talking integration tests)

Anyways, you have an if statement in a function. It must be tested by a unit test. Constructor of function.

HankTheTank
  • 201
  • 1
  • 3
  • Your first paragraph seems to say don't test it and your second seems to say test it. I don't know what you mean. Could you clarify? Thanks. – w0051977 Mar 04 '18 at 19:58
  • Are you able to answer the question in my comment above? Thanks. – w0051977 Mar 05 '18 at 17:44
  • @w0051977 I think I did not write that very well. Bottom line is, there is behavior, there must be a test for it. I'll change my answer – HankTheTank Mar 05 '18 at 18:02