Testing abstract SettingConverter with mocks

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
2
down vote

favorite
2












One of my frameworks uses the ISettingConverter interface as an abstraction for serialization.



public interface ISettingConverter

[NotNull]
object Deserialize([NotNull] object value, [NotNull] Type targetType);

[NotNull]
object Serialize([NotNull] object value);



It is implemented by the abstract SettingConverter class that provides logic that prevents unnecessary calls to actual implementations and that can fallback to a default target type for serialization (the first type on the list) if the target does not support the type of the value natively. A target can be a database or an app.config or the windows registry (which natively supports more types then just strings).



public abstract class SettingConverter : ISettingConverter

private readonly ISet<Type> _supportedTypes;

private readonly Type _fallbackType;

protected SettingConverter(IEnumerable<Type> supportedTypes)

_supportedTypes = new HashSet<Type>(supportedTypes ?? throw new ArgumentNullException(nameof(supportedTypes)));
_fallbackType = supportedTypes.FirstOrDefault() ?? throw new ArgumentException("There must be at least one supprted type.");


public object Deserialize(object value, Type targetType)

return
value.GetType() == targetType
? value
: DeserializeCore(value, targetType);


[NotNull]
protected abstract object DeserializeCore([NotNull]object value, [NotNull] Type targetType);

public object Serialize(object value)

var targetType =
_supportedTypes.Contains(value.GetType())
? value.GetType()
: _fallbackType;

return
value.GetType() == targetType
? value
: SerializeCore(value, targetType);


[NotNull]
protected abstract object SerializeCore([NotNull]object value, [NotNull] Type targetType);




To test this base class I wrote a couple of tests using the free version of the JustMock framework and the MSTest engine with Visual Studio 2017.




The first test makes sure that DeserializeCore is not called if the type of the value already has the target type.



 [TestMethod]
public void Deserialize_ValueHasTargetType_DeserializeCoreNotCalled()

var settingConverter = Mock.Create<SettingConverter>(Behavior.CallOriginal, (IEnumerable<Type>)new typeof(string) );

Mock
.NonPublic
.Arrange<object>(
settingConverter,
"DeserializeCore",
ArgExpr.IsAny<object>(),
ArgExpr.IsAny<Type>())
.OccursNever();

var result = settingConverter.Deserialize("foo", typeof(string));

settingConverter.Assert();
Assert.AreEqual("foo", result);




Then I have a test to make sure the opposite, this is, DeserializeCore must be called if the type of the value is not one of the target types. In this case int != string.



 [TestMethod]
public void Deserialize_ValueHasOtherType_DeserializeCoreCalled()

var settingConverter = Mock.Create<SettingConverter>(Behavior.CallOriginal, (IEnumerable<Type>)new typeof(string) );

Mock
.NonPublic
.Arrange<object>(
settingConverter,
"DeserializeCore",
ArgExpr.IsAny<object>(),
ArgExpr.IsAny<Type>())
.OccursOnce();

settingConverter.Deserialize("foo", typeof(int));

settingConverter.Assert();




The other two tests make sure that serialization does what it is supposed to. So the first test verifies that SerializeCore is not called because the type of the value alread is the same as one of the types that the target supports.



 [TestMethod]
public void Serialize_ValueHasSupportedType_SerializeCoreNotCalled()

var settingConverter = Mock.Create<SettingConverter>(Behavior.CallOriginal, (IEnumerable<Type>)new typeof(string) );

Mock
.NonPublic
.Arrange<object>(
settingConverter,
"SerializeCore",
ArgExpr.IsAny<object>(),
ArgExpr.IsAny<Type>())
.OccursNever();

settingConverter.Serialize("foo");

settingConverter.Assert();




The last tests verifies that SerializeCore is called with a fallback type which in this case is the string because int is not supported and must be converted first.



 [TestMethod]
public void Serialize_ValueHasUnsupportedType_SerializeCoreCalledWithFallbackType()

var settingConverter = Mock.Create<SettingConverter>(Behavior.CallOriginal, (IEnumerable<Type>)new typeof(string) );

Mock
.NonPublic
.Arrange<object>(
settingConverter,
"SerializeCore",
ArgExpr.IsAny<object>(),
ArgExpr.Matches<Type>(t => t == typeof(string)))
.OccursOnce();

settingConverter.Serialize(123);

settingConverter.Assert();




I'd like you take a look at these tests and tell me how good or bad they are and what would you improve if anything? Is their purpose and implementation clear? Did I pick the right names for everything?







share|improve this question

























    up vote
    2
    down vote

    favorite
    2












    One of my frameworks uses the ISettingConverter interface as an abstraction for serialization.



    public interface ISettingConverter

    [NotNull]
    object Deserialize([NotNull] object value, [NotNull] Type targetType);

    [NotNull]
    object Serialize([NotNull] object value);



    It is implemented by the abstract SettingConverter class that provides logic that prevents unnecessary calls to actual implementations and that can fallback to a default target type for serialization (the first type on the list) if the target does not support the type of the value natively. A target can be a database or an app.config or the windows registry (which natively supports more types then just strings).



    public abstract class SettingConverter : ISettingConverter

    private readonly ISet<Type> _supportedTypes;

    private readonly Type _fallbackType;

    protected SettingConverter(IEnumerable<Type> supportedTypes)

    _supportedTypes = new HashSet<Type>(supportedTypes ?? throw new ArgumentNullException(nameof(supportedTypes)));
    _fallbackType = supportedTypes.FirstOrDefault() ?? throw new ArgumentException("There must be at least one supprted type.");


    public object Deserialize(object value, Type targetType)

    return
    value.GetType() == targetType
    ? value
    : DeserializeCore(value, targetType);


    [NotNull]
    protected abstract object DeserializeCore([NotNull]object value, [NotNull] Type targetType);

    public object Serialize(object value)

    var targetType =
    _supportedTypes.Contains(value.GetType())
    ? value.GetType()
    : _fallbackType;

    return
    value.GetType() == targetType
    ? value
    : SerializeCore(value, targetType);


    [NotNull]
    protected abstract object SerializeCore([NotNull]object value, [NotNull] Type targetType);




    To test this base class I wrote a couple of tests using the free version of the JustMock framework and the MSTest engine with Visual Studio 2017.




    The first test makes sure that DeserializeCore is not called if the type of the value already has the target type.



     [TestMethod]
    public void Deserialize_ValueHasTargetType_DeserializeCoreNotCalled()

    var settingConverter = Mock.Create<SettingConverter>(Behavior.CallOriginal, (IEnumerable<Type>)new typeof(string) );

    Mock
    .NonPublic
    .Arrange<object>(
    settingConverter,
    "DeserializeCore",
    ArgExpr.IsAny<object>(),
    ArgExpr.IsAny<Type>())
    .OccursNever();

    var result = settingConverter.Deserialize("foo", typeof(string));

    settingConverter.Assert();
    Assert.AreEqual("foo", result);




    Then I have a test to make sure the opposite, this is, DeserializeCore must be called if the type of the value is not one of the target types. In this case int != string.



     [TestMethod]
    public void Deserialize_ValueHasOtherType_DeserializeCoreCalled()

    var settingConverter = Mock.Create<SettingConverter>(Behavior.CallOriginal, (IEnumerable<Type>)new typeof(string) );

    Mock
    .NonPublic
    .Arrange<object>(
    settingConverter,
    "DeserializeCore",
    ArgExpr.IsAny<object>(),
    ArgExpr.IsAny<Type>())
    .OccursOnce();

    settingConverter.Deserialize("foo", typeof(int));

    settingConverter.Assert();




    The other two tests make sure that serialization does what it is supposed to. So the first test verifies that SerializeCore is not called because the type of the value alread is the same as one of the types that the target supports.



     [TestMethod]
    public void Serialize_ValueHasSupportedType_SerializeCoreNotCalled()

    var settingConverter = Mock.Create<SettingConverter>(Behavior.CallOriginal, (IEnumerable<Type>)new typeof(string) );

    Mock
    .NonPublic
    .Arrange<object>(
    settingConverter,
    "SerializeCore",
    ArgExpr.IsAny<object>(),
    ArgExpr.IsAny<Type>())
    .OccursNever();

    settingConverter.Serialize("foo");

    settingConverter.Assert();




    The last tests verifies that SerializeCore is called with a fallback type which in this case is the string because int is not supported and must be converted first.



     [TestMethod]
    public void Serialize_ValueHasUnsupportedType_SerializeCoreCalledWithFallbackType()

    var settingConverter = Mock.Create<SettingConverter>(Behavior.CallOriginal, (IEnumerable<Type>)new typeof(string) );

    Mock
    .NonPublic
    .Arrange<object>(
    settingConverter,
    "SerializeCore",
    ArgExpr.IsAny<object>(),
    ArgExpr.Matches<Type>(t => t == typeof(string)))
    .OccursOnce();

    settingConverter.Serialize(123);

    settingConverter.Assert();




    I'd like you take a look at these tests and tell me how good or bad they are and what would you improve if anything? Is their purpose and implementation clear? Did I pick the right names for everything?







    share|improve this question





















      up vote
      2
      down vote

      favorite
      2









      up vote
      2
      down vote

      favorite
      2






      2





      One of my frameworks uses the ISettingConverter interface as an abstraction for serialization.



      public interface ISettingConverter

      [NotNull]
      object Deserialize([NotNull] object value, [NotNull] Type targetType);

      [NotNull]
      object Serialize([NotNull] object value);



      It is implemented by the abstract SettingConverter class that provides logic that prevents unnecessary calls to actual implementations and that can fallback to a default target type for serialization (the first type on the list) if the target does not support the type of the value natively. A target can be a database or an app.config or the windows registry (which natively supports more types then just strings).



      public abstract class SettingConverter : ISettingConverter

      private readonly ISet<Type> _supportedTypes;

      private readonly Type _fallbackType;

      protected SettingConverter(IEnumerable<Type> supportedTypes)

      _supportedTypes = new HashSet<Type>(supportedTypes ?? throw new ArgumentNullException(nameof(supportedTypes)));
      _fallbackType = supportedTypes.FirstOrDefault() ?? throw new ArgumentException("There must be at least one supprted type.");


      public object Deserialize(object value, Type targetType)

      return
      value.GetType() == targetType
      ? value
      : DeserializeCore(value, targetType);


      [NotNull]
      protected abstract object DeserializeCore([NotNull]object value, [NotNull] Type targetType);

      public object Serialize(object value)

      var targetType =
      _supportedTypes.Contains(value.GetType())
      ? value.GetType()
      : _fallbackType;

      return
      value.GetType() == targetType
      ? value
      : SerializeCore(value, targetType);


      [NotNull]
      protected abstract object SerializeCore([NotNull]object value, [NotNull] Type targetType);




      To test this base class I wrote a couple of tests using the free version of the JustMock framework and the MSTest engine with Visual Studio 2017.




      The first test makes sure that DeserializeCore is not called if the type of the value already has the target type.



       [TestMethod]
      public void Deserialize_ValueHasTargetType_DeserializeCoreNotCalled()

      var settingConverter = Mock.Create<SettingConverter>(Behavior.CallOriginal, (IEnumerable<Type>)new typeof(string) );

      Mock
      .NonPublic
      .Arrange<object>(
      settingConverter,
      "DeserializeCore",
      ArgExpr.IsAny<object>(),
      ArgExpr.IsAny<Type>())
      .OccursNever();

      var result = settingConverter.Deserialize("foo", typeof(string));

      settingConverter.Assert();
      Assert.AreEqual("foo", result);




      Then I have a test to make sure the opposite, this is, DeserializeCore must be called if the type of the value is not one of the target types. In this case int != string.



       [TestMethod]
      public void Deserialize_ValueHasOtherType_DeserializeCoreCalled()

      var settingConverter = Mock.Create<SettingConverter>(Behavior.CallOriginal, (IEnumerable<Type>)new typeof(string) );

      Mock
      .NonPublic
      .Arrange<object>(
      settingConverter,
      "DeserializeCore",
      ArgExpr.IsAny<object>(),
      ArgExpr.IsAny<Type>())
      .OccursOnce();

      settingConverter.Deserialize("foo", typeof(int));

      settingConverter.Assert();




      The other two tests make sure that serialization does what it is supposed to. So the first test verifies that SerializeCore is not called because the type of the value alread is the same as one of the types that the target supports.



       [TestMethod]
      public void Serialize_ValueHasSupportedType_SerializeCoreNotCalled()

      var settingConverter = Mock.Create<SettingConverter>(Behavior.CallOriginal, (IEnumerable<Type>)new typeof(string) );

      Mock
      .NonPublic
      .Arrange<object>(
      settingConverter,
      "SerializeCore",
      ArgExpr.IsAny<object>(),
      ArgExpr.IsAny<Type>())
      .OccursNever();

      settingConverter.Serialize("foo");

      settingConverter.Assert();




      The last tests verifies that SerializeCore is called with a fallback type which in this case is the string because int is not supported and must be converted first.



       [TestMethod]
      public void Serialize_ValueHasUnsupportedType_SerializeCoreCalledWithFallbackType()

      var settingConverter = Mock.Create<SettingConverter>(Behavior.CallOriginal, (IEnumerable<Type>)new typeof(string) );

      Mock
      .NonPublic
      .Arrange<object>(
      settingConverter,
      "SerializeCore",
      ArgExpr.IsAny<object>(),
      ArgExpr.Matches<Type>(t => t == typeof(string)))
      .OccursOnce();

      settingConverter.Serialize(123);

      settingConverter.Assert();




      I'd like you take a look at these tests and tell me how good or bad they are and what would you improve if anything? Is their purpose and implementation clear? Did I pick the right names for everything?







      share|improve this question











      One of my frameworks uses the ISettingConverter interface as an abstraction for serialization.



      public interface ISettingConverter

      [NotNull]
      object Deserialize([NotNull] object value, [NotNull] Type targetType);

      [NotNull]
      object Serialize([NotNull] object value);



      It is implemented by the abstract SettingConverter class that provides logic that prevents unnecessary calls to actual implementations and that can fallback to a default target type for serialization (the first type on the list) if the target does not support the type of the value natively. A target can be a database or an app.config or the windows registry (which natively supports more types then just strings).



      public abstract class SettingConverter : ISettingConverter

      private readonly ISet<Type> _supportedTypes;

      private readonly Type _fallbackType;

      protected SettingConverter(IEnumerable<Type> supportedTypes)

      _supportedTypes = new HashSet<Type>(supportedTypes ?? throw new ArgumentNullException(nameof(supportedTypes)));
      _fallbackType = supportedTypes.FirstOrDefault() ?? throw new ArgumentException("There must be at least one supprted type.");


      public object Deserialize(object value, Type targetType)

      return
      value.GetType() == targetType
      ? value
      : DeserializeCore(value, targetType);


      [NotNull]
      protected abstract object DeserializeCore([NotNull]object value, [NotNull] Type targetType);

      public object Serialize(object value)

      var targetType =
      _supportedTypes.Contains(value.GetType())
      ? value.GetType()
      : _fallbackType;

      return
      value.GetType() == targetType
      ? value
      : SerializeCore(value, targetType);


      [NotNull]
      protected abstract object SerializeCore([NotNull]object value, [NotNull] Type targetType);




      To test this base class I wrote a couple of tests using the free version of the JustMock framework and the MSTest engine with Visual Studio 2017.




      The first test makes sure that DeserializeCore is not called if the type of the value already has the target type.



       [TestMethod]
      public void Deserialize_ValueHasTargetType_DeserializeCoreNotCalled()

      var settingConverter = Mock.Create<SettingConverter>(Behavior.CallOriginal, (IEnumerable<Type>)new typeof(string) );

      Mock
      .NonPublic
      .Arrange<object>(
      settingConverter,
      "DeserializeCore",
      ArgExpr.IsAny<object>(),
      ArgExpr.IsAny<Type>())
      .OccursNever();

      var result = settingConverter.Deserialize("foo", typeof(string));

      settingConverter.Assert();
      Assert.AreEqual("foo", result);




      Then I have a test to make sure the opposite, this is, DeserializeCore must be called if the type of the value is not one of the target types. In this case int != string.



       [TestMethod]
      public void Deserialize_ValueHasOtherType_DeserializeCoreCalled()

      var settingConverter = Mock.Create<SettingConverter>(Behavior.CallOriginal, (IEnumerable<Type>)new typeof(string) );

      Mock
      .NonPublic
      .Arrange<object>(
      settingConverter,
      "DeserializeCore",
      ArgExpr.IsAny<object>(),
      ArgExpr.IsAny<Type>())
      .OccursOnce();

      settingConverter.Deserialize("foo", typeof(int));

      settingConverter.Assert();




      The other two tests make sure that serialization does what it is supposed to. So the first test verifies that SerializeCore is not called because the type of the value alread is the same as one of the types that the target supports.



       [TestMethod]
      public void Serialize_ValueHasSupportedType_SerializeCoreNotCalled()

      var settingConverter = Mock.Create<SettingConverter>(Behavior.CallOriginal, (IEnumerable<Type>)new typeof(string) );

      Mock
      .NonPublic
      .Arrange<object>(
      settingConverter,
      "SerializeCore",
      ArgExpr.IsAny<object>(),
      ArgExpr.IsAny<Type>())
      .OccursNever();

      settingConverter.Serialize("foo");

      settingConverter.Assert();




      The last tests verifies that SerializeCore is called with a fallback type which in this case is the string because int is not supported and must be converted first.



       [TestMethod]
      public void Serialize_ValueHasUnsupportedType_SerializeCoreCalledWithFallbackType()

      var settingConverter = Mock.Create<SettingConverter>(Behavior.CallOriginal, (IEnumerable<Type>)new typeof(string) );

      Mock
      .NonPublic
      .Arrange<object>(
      settingConverter,
      "SerializeCore",
      ArgExpr.IsAny<object>(),
      ArgExpr.Matches<Type>(t => t == typeof(string)))
      .OccursOnce();

      settingConverter.Serialize(123);

      settingConverter.Assert();




      I'd like you take a look at these tests and tell me how good or bad they are and what would you improve if anything? Is their purpose and implementation clear? Did I pick the right names for everything?









      share|improve this question










      share|improve this question




      share|improve this question









      asked Jan 26 at 20:31









      t3chb0t

      32.1k54195




      32.1k54195

























          active

          oldest

          votes











          Your Answer




          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f186083%2ftesting-abstract-settingconverter-with-mocks%23new-answer', 'question_page');

          );

          Post as a guest



































          active

          oldest

          votes













          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes










           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f186083%2ftesting-abstract-settingconverter-with-mocks%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          Chat program with C++ and SFML

          Function to Return a JSON Like Objects Using VBA Collections and Arrays

          Will my employers contract hold up in court?