15

次のクラスのメソッドをユニットテストしたい

public class DeviceAuthorisationService : IDeviceAuthorisationService
{
    private DeviceDetailsDTO deviceDetailsDTO = null;
    private IDeviceAuthorisationRepositiory deviceAuthorisationRepositiory;

    public DeviceAuthorisationService(IDeviceAuthorisationRepositioryService paramDeviceAuthorisationRepository)
    {
        deviceAuthorisationRepositiory = paramDeviceAuthorisationRepository;
    }

    public void AuthoriseDeviceProfile(long paramUserID, string paramClientMakeModel)
    {
        if (deviceDetailsDTO == null)
            GetCellPhoneDetails(userID);

        if (deviceDetailsDTO.IsDeviceSelected == false)
            throw new SomeCustomExceptionA();

        if (deviceDetailsDTO.CellPhoneMakeModel.ToLower() != paramClientMakeModel.ToLower())
            throw new SomeCustomExceptionB;
    }

    public void UpdateDeviceStatusToActive(long userID)
    {
        if (deviceDetailsDTO == null)
            throw new InvalidOperationException("UnAuthorised Device Profile Found Exception");

        if (deviceDetailsDTO.PhoneStatus != (short)Status.Active.GetHashCode())
            deviceAuthorisationRepositiory.UpdatePhoneStatusToActive(deviceDetailsDTO.DeviceID);
    }

    private void GetCellPhoneDetails(long userID)
    {
        deviceDetailsDTO = deviceAuthorisationRepositiory.GetSelectedPhoneDetails(userID);

        if (deviceDetailsDTO == null)
            throw new SomeCustomException()
    }

}

ノート:

  • メソッド名=AuthoriseDeviceProfileはvoidを返します
  • このメソッドは、userSentMakeModelをdbmatchに格納されているものと照合します
  • 一致する場合-単に戻ります(つまり、状態を変更しません)

このメソッドをどのように単体テストしますか?

  • レポを嘲笑しました
  • 「THROWSEXCEPTION」のシナリオをカバーしました
  • 問題は、ALL WENTWELLのシナリオをユニットテストする方法です。つまり、ユーザーのmakeModelがリポジトリと一致します。

これをテスト可能にするための設計上の提案は大歓迎です。よろしくお願いします。

4

6 に答える 6

15

メソッドはvoidを返すため、テスト/アサートできる副作用がある可能性があります。

あなたの場合、オプションはのモックインスタンスを提供することですIDeviceAuthorisationRepositioryService。次に、への呼び出しUpdatePhoneStatusToActiveが発生したかどうかを確認できます。Moqを使用したソリューションは次のとおりです。

var mock = new Mock<IDeviceAuthorisationRepositioryService>();

var service = new DeviceAuthorisationService(mock.Object);
service.UpdateDeviceStatusToActive(....);

mock.Verify(x => service.UpdatePhoneStatusToActive(), Times.Never());
于 2012-12-11T12:57:47.550 に答える
7

メソッドが無効である場合、それはいくつかの観察可能な副作用を持っているはずです-そうでなければ、それは無意味です。したがって、戻り値をテストする代わりに、副作用をテストします。この場合、おそらくどのような状況でどの例外がスローされるかということのように見えます。

(ここでは、「例外をスローする」は副作用と見なされます。もちろん、暗黙的な種類の戻り値と考えることもできます...)

于 2012-12-11T12:53:59.997 に答える
5

モックされたリポジトリを注入します。リポジトリ上の特定のメソッドが呼び出されているかどうかをテストします。

于 2012-12-11T12:55:20.653 に答える
3

単体テストで例外の期待値を設定できます。nUnitでは、次のようになります。

[Test]
[ExpectedException(typeof(InvalidOperationException))]
public void TestAuthoriseFail()
{
    // do something that should make the tested method throw the exception
}
于 2012-12-11T12:55:07.870 に答える
2

メソッドがvoidを返したとしても、それはあなたにとって有用な何かをしているに違いありません(そうでなければ、それは無意味なメソッドになります)。

AuthoriseDeviceProfileあなたのコードから、メソッドが実行している「便利な」ことには本質的に2つのフレーバーがあると思います。

  • GetSelectedPhoneDetailsでメソッドを呼び出すIDeviceAuthorisationRepositiory
  • 特定の条件に基づいてさまざまな例外をスローする

したがって、メソッドを単体テストするには、これに対応する2つのことを行う必要があります。

  • モックを注入し、呼び出されIDeviceAuthorisationRepositioryたかどうかを記録および/またはアサートしますGetSelectedPhoneDetails
  • さまざまな例外を誘発するテストメソッドを実行し、スローされたときにそれらをキャプチャして、次のことを確認します。
    • 例外が実際にスローされます
    • スローされる例外は、各シナリオに適切なものです。
于 2012-12-11T13:05:32.380 に答える
0
  [TestMethod]
        public void AuthoriseDeviceProfileTest()
        {
            long paramUserID=1, string paramClientMakeModel=test";
            IDeviceAuthorisationService DeviceAuthorisationService= new DeviceAuthorisationService();

            try
            {

                DeviceAuthorisationService.AuthoriseDeviceProfile(paramUserID, paramClientMakeModel);
                Assert.IsNull(paramUserID);

            }
            catch (Exception e)
            {
                Assert.AreNotEqual("Exception of type was thrown", e.Message);
            }
        }
    }
于 2018-05-14T12:50:35.950 に答える