0

I recently received some feedback about some tests we wrote a long time ago from a contractor for a legacy application. I am confused with the terminology that he used and I won't get chance to talk to him again for another month (when I will speak to him). Please see the code below:

 [TestMethod]
        public void Is_Correct_Months()
        {
            IService service = new Service();

            DataTable t1 = service.GetMonths();
            DataTable t2 = BuildExpectedTable();

            Assert.IsNotNull(t1);
            Assert.AreEqual(t1.Rows.Count, t2.Rows.Count);

            for (int i = 0; i <= 2; i++)
            {
                Assert.AreEqual(t1.Rows[i][0], t2.Rows[i][0]);
                Assert.AreEqual(t1.Rows[i][1], t2.Rows[i][1]);
            }
        }

        public DataTable BuildExpectedTable()
        {
            DataTable dt = new DataTable();
            //Add column names to datatable
            dt.Columns.Add("Column1", typeof(string));
            dt.Rows.Add("January");
            dt.Rows.Add("May");
            dt.Rows.Add("December");
            return dt;
        }

Question: Is the BuildExpectedTable method a Stub or not in this case? Is it a bad idea to Assert against BuildExpectedTable (as I have done)?

Now see the code below:

 var mockCalculator = new Moq.Mock<ICalculator>();
            mockChangeCalculator.SetupProperty(client => client.Number1, 400).SetupProperty(client => client.Number2, 200);

This is obviously a mock. Question: Could it ever be construed as a Stub?

Now see the code below:

int[] values = new int[] { 1, 3, 5, 9 };
 
    IEnumerable<int> processed = ProcessInput(values);
 
    int[] expected = new int[] { 1, 9, 25, 81 };
    CollectionAssert.AreEqual(expected, processed);

Question: Is expected a stub in this case?

Update

[TestMethod]
            public void Is_Correct_Months()
            {
                IService service = new Service();

                DataTable t1 = service.GetMonths();

                DataTable dt2 = new DataTable();
                //Add column names to datatable
                dt.Columns.Add("Column1", typeof(string));
                dt.Rows.Add("January");
                dt.Rows.Add("May");
                dt.Rows.Add("December");

                Assert.IsNotNull(t1);
                Assert.AreEqual(t1.Rows.Count, t2.Rows.Count);

                for (int i = 0; i <= 2; i++)
                {
                    Assert.AreEqual(t1.Rows[i][0], t2.Rows[i][0]);
                    Assert.AreEqual(t1.Rows[i][1], t2.Rows[i][1]);
                }
            }
w0051977
  • 15,099
  • 32
  • 152
  • 329
  • @dlatikay, thanks. I have updated the question. I tried to simplify it and did not update the for loop. – w0051977 Jan 21 '18 at 12:40
  • related: https://stackoverflow.com/a/346440/1132334 – Cee McSharpface Jan 21 '18 at 12:44
  • @dlatikay, thanks for the link, however I have already read it among many others. Are you able to answer the three questions in my post? – w0051977 Jan 21 '18 at 12:53
  • Could you post the code for service.GetMonths? – Ken Tucker Jan 21 '18 at 13:10
  • @w0051977 I'm not sure I'm really clear about what you're actually asking. IMO possible answers will contain the usual nitpicking on terminology. strictly speaking, `expected` is not a stub, it's just data. a stub is at least a routine (method, function). – Cee McSharpface Jan 21 '18 at 13:28
  • @dlatikay, is BuildExpectedTable a stub? – w0051977 Jan 21 '18 at 13:50
  • @Ken Tucker, GetMonths is just a function that returns a DataTable with three rows i.e. January; May and December. – w0051977 Jan 21 '18 at 13:51
  • 1
    My nitpick is that I wouldn't even call this a unit test if `IService` is not mocked. It is an integration test. Of course it would make the (maybe) stub irrelevant. – Crowcoder Jan 21 '18 at 14:22
  • @Crowder, that is exactly what he said. Could you clarify what you mean by "irrelevant"? (perhaps in an answer - so that I can give credit). – w0051977 Jan 21 '18 at 14:28
  • I don't really think I have an appropriate answer for the questions, I'm just saying if `IService` is mocked then you are testing that the mock data, which you presumably hard-coded, is equal to the stub data that your hard-coded. Not much point in that test. I don't even unit test the data layer (I do integration test), I test the logic layer because that is where you actually have something to assert. – Crowcoder Jan 21 '18 at 14:37
  • @Crowcoder do you assert anything when testing the data layer? – w0051977 Jan 21 '18 at 15:59
  • My asserts in the data layer are very basic. Usually just checking for nulls or counts greater than zero. Sometimes asserting lookup values as you are doing. We have a very reliable data layer that just execs stored procedures that have no business logic. All I need to test in that layer is that the right procedure is called and various inputs don't blow it up. The tests that run on the data layer are not run on the build server because it gets very complicated to test live data reliably. – Crowcoder Jan 21 '18 at 16:23
  • @Crowcoder, if you are "asserting lookup values", then would you not need a stub? – w0051977 Jan 21 '18 at 16:50
  • Yes but I wouldn't do that if the service was mocked. It is not clear if yours is or isn't (though my guess would be not) I'm just saying its an integration test, not unit test if you hit a live service . – Crowcoder Jan 21 '18 at 17:33
  • Actually after thinking about it, no I wouldn't stub out lookup values for the sake of asserting them. I would stub them out if something in the logic layer was using them. – Crowcoder Jan 21 '18 at 17:53
  • Related, maybe of interest is one of my blog posts https://contrivedexample.com/2017/11/05/organizing-service-mocks-in-unit-tests/ – Crowcoder Jan 21 '18 at 17:56
  • @Crowcoder, nice article. I think I may have to read it again though. What would you assert to if you were not using a stub? – w0051977 Jan 21 '18 at 18:18
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/163595/discussion-between-crowcoder-and-w0051977). – Crowcoder Jan 21 '18 at 19:14
  • Have a look e.g. [here](https://stackoverflow.com/a/3459431/863240) what `stub` is and what `mock` is. According to that `BuildExpectedTable` is not stub, it just produces expected result. The `mockCalculator` could act as stub but could act as mock, depends how it is used in the test. HTH – Daniel Dušek Jan 27 '18 at 12:03
  • @dee, thanks. I have shown how they are used in the test. Would you describe it as a stub or mock in this case? – w0051977 Jan 27 '18 at 12:07
  • Those both calculators could act as `mock objects` in case when they can make the test fail, which means you will assert against some quality of them _(Mock is smarter stub. You verify Your test passes through it)._ – Daniel Dušek Jan 27 '18 at 20:51
  • But they could act as `stubs` as well in case when they are used in the test only to fake some external dependencies, which are necessary to make the test running, but which don't have any influence to the test itself _(Stub is simple fake object. It just makes sure test runs smoothly)._ It is not possible to say, if `mock/Change/Calculator` act as mock or stub. We need to see the whole test. But if you assert against it (`Asser.IsTrue(mockCalculator.Result==123)` etc.) , then it is `mock object`. Otherwise it is `stub` – Daniel Dušek Jan 27 '18 at 20:56
  • I like [this book](https://www.manning.com/books/the-art-of-unit-testing). HTH – Daniel Dušek Jan 27 '18 at 21:03
  • @dee, what do you think the contractor meant by: "You are stubbing a simple data object"? Thanks. – w0051977 Jan 27 '18 at 21:33
  • As I understand the terminology, stubs are fake objects which are used to simulate the state of external dependencies (like some external service call, file system, database etc.) so the test can run. Stubbing simple data object seems to be not necessary, because ...it is just simple data object? – Daniel Dušek Jan 27 '18 at 21:49
  • Thanks. However, I realise that. I am trying to understand what the data object stub is in the question. – w0051977 Jan 27 '18 at 22:34

0 Answers0