3
\$\begingroup\$

Is the following MS VS solution structure and classes OK w.r.t. easy unit tests with dependency injection? Would your unit tests look similar?

If you call the calculations below over a WPF module, would you skip a test over the WPF since complicated, or would you still conisder testing it over the WPF module ?

Solution

  1. ProjectWork

    Classes

    • IDev.cs

      public interface IDev
      {
        IToMeasure Measure();
      }
      public interface IToMeasure
      {
        double Value{ get; set; }
      }
      
    • CalculatingUnit.cs

      public class CalculatingUnit
      {
         int count = 0,
             maxMeasuredValues = 20;
      
         public double doMeasures(IDev myDevice)
         {
            // simulating measuring each Xms
            while (count < maxMeasuredValues ) 
            {
               return myDevice.Measure();
               count++;
            }
         }
      }
      
    • MyDevice.cs

      // non-deterministic (random) values
      public class MyDevice: IDev
      {
         private readonly MyRandom myRandomVar = new Random(0); 
      
         public IToMeasure Measure()
         {
            var meas = new Measure { Value = myRandomVar.NextRandom(2, 0.5) };
            return meas;
         }
      }
      
    • TestDevice.cs

      // deterministic values
      public class TestDevice : IDevice
      {
         int nrValues = 6;
         int gIdx = 0,
         gCount = 0;
         int[] testMeasures = { 1, 2, 3, 4, 5, 6 };
      
         public IToMeasure Measure()
         {
            gIdx = gCount % nrValues;
            var meas = new Measure { Value = testMeasures[gIdx] };
            gCount++;
      
            return meas;
         }
      }
      
    • myDeviceWPF.cs // it seems complicated testing over WPF, so I dont test with it, would you also skip it ?

      class myDeviceViewModel : INotifyPropertyChanged
      {
        ...
      }
      
  2. ProjectTest

    • myDevice_Test.cs

      [TestClass]
      public class myDevice_Test
      {
          [TestMethod]
          public void Test_doMeasures()
          {
              double actual = 1;
              double expected = 21.068;
      
              TestDevice myDevice;
              CalculatingUnit myCalculatingUnit;
      
              myDevice = new TestDevice();
              myCalculatingUnit = new CalculatingUnit();
      
              actual = myCalculatingUnit.doMeasures(myDevice );
              Assert.AreEqual(expected, actual , 0.001, "Wrong calculations");
          }
      }
      
\$\endgroup\$
2
  • \$\begingroup\$ in your MyDevice.cs file you are missing a closing } sure it was a typo but thought I would point it out \$\endgroup\$
    – Malachi
    Mar 20 '15 at 13:13
  • \$\begingroup\$ @Malachi : 10x. Yes, it was a typo. I just corrected it. \$\endgroup\$ Mar 22 '15 at 8:32
2
\$\begingroup\$

First, some quality/stylistic comments:

This won't do what you want/isn't legal:

  while (count < maxMeasuredValues ) 
  {
     return myDevice.Measure();
     count++;
  }

// non-deterministic (random) values
private readonly MyRandom myRandomVar = new Random(0); 

Random initialized with a fixed seed is deterministic. Even with no seed (current time) it is technically deterministic, but that's pickier. Also, I don't see how you are using MyDevice in the code sample.

    double actual = 1;
    double expected = 21.068;

    TestDevice myDevice;
    CalculatingUnit myCalculatingUnit;

    myDevice = new TestDevice();
    myCalculatingUnit = new CalculatingUnit();

    actual = myCalculatingUnit.doMeasures(myDevice );

In general, prefer to declare and assign a value at the same time. This will make the functions shorter and more readable.

Other than that, the organization looks fine.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.