質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.76%

  • C#

    6563questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Visual Studio 2012

    90questions

    Microsoft Visual Studio 2012は、Microsoftによる統合開発環境(IDE)であり、多種多様なプログラミング言語に対応しています。 Visual Studio 2010の次のバージョンです

readlineとdrawstringの所で例外を意図的に発生させたい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 515

hinatti

score 6

前提・実現したいこと

作成したプログラムの単体テストをしているのですがreadLineとdrawstringの所で意図的に例外を発生させたい

該当のソースコード

/// <summary>
        /// FormProductDisplayのイベントハンドラ
        /// DBに接続して任意のファイルをINSERTする
        /// </summary>
        /// <param name="sender">使用しない</param>
        /// <param name="e">使用しない</param>
        private void FormProductDisplay_Load(object sender, EventArgs e)
        {
            string sqlDelete = @"DELETE FROM product_table";

            using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.ConnectionString))
            using (SqlCommand command = new SqlCommand(sqlDelete, connection))
            {
                try
                {
                    connection.Open();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("データベースを開くのに失敗しました。", "error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
                    return;
                }

                try
                {
                    command.ExecuteNonQuery();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("SQL文を実行出来ませんでした。", "error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
                    return;
                }
            }

            string filePath;
            using (OpenFileDialog dialog = new OpenFileDialog())
            {
                dialog.FileName = "default.txt";
                dialog.InitialDirectory = "";
                dialog.Title = "開くファイルを選択してください。";
                dialog.RestoreDirectory = true;
                dialog.CheckFileExists = false;
                TopMost = false;

                if (dialog.ShowDialog() == DialogResult.Cancel)
                {
                    return;
                }

                filePath = dialog.FileName;
            }

            using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.ConnectionString))
            {
                string sqlInsert = @"
INSERT INTO product_table (
product_id,
basic_order_lot,
product_code,
chassis_number,
assembled_ymd,
assembled_hms,
struct_number,
yyyymm
)
VALUES (
@product_id,
@basic_order_lot,
@product_code,
@chassis_number,
@assembled_ymd,
@assembled_hms,
@struct_number,
@yyyymm
);
";
                try
                {
                    connection.Open();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("データベースを開くのに失敗しました。", "error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
                    return;
                }

                using (SqlCommand command = new SqlCommand(sqlInsert, connection))
                {
                    FileStream stream;

                    try
                    {
                        stream = File.Open(filePath, FileMode.Open);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("ファイルを開くのに失敗しました。", "error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        System.Diagnostics.Debug.WriteLine(ex.ToString());
                        return;
                    }

                    using (StreamReader read = new StreamReader(stream))
                    {
                        while (read.EndOfStream == false)
                        {
                            string line;
                            try
                            {
                                line = read.ReadLine();
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show("ファイルの読み込みに失敗しました。", "error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                System.Diagnostics.Debug.WriteLine(ex.ToString());
                                return;
                            }

                            if (line == null)
                            {
                                break;
                            }

                            command.Parameters.AddWithValue("@product_id",      line.Substring(0, 11));
                            command.Parameters.AddWithValue("@basic_order_lot", line.Substring(11,  8));
                            command.Parameters.AddWithValue("@product_code",    line.Substring(19,  6));
                            command.Parameters.AddWithValue("@chassis_number",  line.Substring(25,  4));
                            command.Parameters.AddWithValue("@assembled_ymd",   line.Substring(29,  8));
                            command.Parameters.AddWithValue("@assembled_hms",   line.Substring(37, 11));
                            command.Parameters.AddWithValue("@struct_number",   line.Substring(48,  7));
                            command.Parameters.AddWithValue("@yyyymm",          line.Substring(55,  6));

                            try
                            {
                                command.ExecuteNonQuery();
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show("データの追加に失敗しました。", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                                System.Diagnostics.Debug.WriteLine(ex.ToString());
                            }
                            command.Parameters.Clear();
                        }
                        read.Close();
                    }
                }
            }
        }
       .
       .
       .
    /// <summary>
        /// 1ページ印刷するイベントハンドラ
        /// 1ページ分の印刷設定
        /// </summary>
        /// <param name="sender">使用しない</param>
        /// <param name="e">使用する</param>
        private void PrintPage(object sender, PrintPageEventArgs e)
        {
            int x, y = 20;
            e.HasMorePages = true;
            Font font = new Font("MS ゴシック", 12);
            var productList = productDataBindingSource.DataSource as List<ProductData>;

            if (productList == null)
            {
                e.HasMorePages = false;
                return;
            }

            for (int i = ((page - 1) * 50); 
                 (i < productList.Count && (i < (page * 50))); 
                 i++)
            {
                ProductData data = productList[i];
                try
                {
                    if (data == null)
                    {
                        return;
                    }

                    x = 30;
                    e.Graphics.DrawString(data.ProductId, font, Brushes.Black, x, y);
                    x = x + 80;
                    e.Graphics.DrawString(data.BasicOrderLot, font, Brushes.Black, x, y);
                    x = x + 90;
                    e.Graphics.DrawString(data.ProductCode, font, Brushes.Black, x, y);
                    x = x + 80;
                    e.Graphics.DrawString(data.ChassisNumber, font, Brushes.Black, x, y);
                    x = x + 60;
                    e.Graphics.DrawString(data.AssembledYmd, font, Brushes.Black, x, y);
                    x = x + 150;
                    e.Graphics.DrawString(data.AssembledHms, font, Brushes.Black, x, y);
                    x = x + 100;
                    e.Graphics.DrawString(data.StructNumber, font, Brushes.Black, x, y);
                    x = x + 100;
                    e.Graphics.DrawString(data.YyyyMm, font, Brushes.Black, x, y);
                    y = y + 20;
                }
                catch (Exception ex)
                {
                    MessageBox.Show("描画出来ませんでした。", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
                    e.HasMorePages = false;
                }
            }

            e.Graphics.DrawString(String.Format("{0}ページ", page), font, Brushes.Black, 365, 1110);
            page++;

            if (productList.Count <= (page - 1) * 50)
            {
                e.HasMorePages = false;
                page = 1;
                return;
            }
        }

試したこと

開いたファイルを消したら読み込みができないんじゃないかと思い実践しようと思ったのですが他のプログラムで開いていたら消去が出来なかったです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

throw new Exception(); というコードを例外を発生させたい行に入れれば「例外を意図的に発生」はできると思うのですが、そういうことではない?

【追記】

コメント欄に、

例外処置の基本として「業務エラー」と「例外」分けて処理するというのがあります。今回の話は「業務エラー」として処置する話ではないかと思います。詳しくはコメント欄に書ききれませんので、回答欄に追記しておきます。

と書きましたが、それを以下に書いておきます。

例外処置について、自分的に一般的に行うべきなのは以下の通りと思っています:

(1) 予測可能で正しい業務フローに戻すことができる「業務エラー」(例:ユーザーの入力間違い)と、予測できないもしくは予測はできても何の対応もできない「例外」(例:DB サーバーダウン)を区別して対処。

(2) 「例外」はランタイムに拾わせてアプリケーションを停止させる。

(3) よほどのことがない限り try-catch は書かない。

(4) キャッチせざるを得ない場合でも Excption はキャッチしない。

(5) 間違って補足してしまった例外は throw する。(注:catch ブロックでキャッチした例外を throw するとスタックトレースが途切れるので単に throw と書く)

(6) ユーザーへの通知が必要なら、集約的例外処置を利用する。

詳しくは以下の記事を見てください。

NETの例外処理 Part.1
https://blogs.msdn.microsoft.com/nakama/2008/12/29/net-part-1/

.NETの例外処理 Part.2
https://blogs.msdn.microsoft.com/nakama/2009/01/02/net-part-2/

あと、.NET 4 からは破損状態例外は catch できなくなっているそうですが、「それでも Catch (Exception e) を使用するのはよくない」ということについては以下の記事を見てください。

破損状態例外を処理する
https://msdn.microsoft.com/ja-jp/magazine/dd419661.aspx

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/15 16:01

    ですね…
    ソースコードをいじらずに例外を発生させたいんです

    キャンセル

  • 2017/09/15 16:04

    目的は何ですか? 何をしたいのですか? 全体的なシナリオ・やりたいことを書いていただけると理解しやすいのですが・・・

    キャンセル

  • 2017/09/15 16:07

    完成したプログラムの単体テストをしたいのです
    テスト項目にファイルが読み込めなかった場合と描画出来なかった場合の項目があるので意図的に例外を発生させたいのです

    キャンセル

  • 2017/09/15 16:33

    実際に「ファイルが読み込めなかった場合」と「描画出来なかった場合」という状況を作ってテストするしかないと思います。

    ただし、そういう状況を作ってテストしたとしても、果たして ReadLine や DrawString が質問者さんが期待するように例外をスローするかどうかは別の話です。

    まずは、質問者さんが「ファイルが読み込めなかった場合」と「描画出来なかった場合」というのが具体的にどういう状況なのかをきちんと明確にして定義し、それを検出するための仕組みを考えるべきと思います。

    その仕組みを実現する上では ReadLine や DrawString がスローする例外に頼る必要はないかもしれません。(そもそも例外を発生させるというやり方は問題ありだと思います)

    例えば、「ファイルが読み込めなかった場合」というのは、ReadLine メソッドを実行する前にチェックできるのではないですか?

    キャンセル

  • 2017/09/15 16:44

    本当は試験項目が合っているかどうか上司がチェックしてくれるのですが今回に限ってチェックしてくれなくて試験項目書が合っているのかどうかも分からないまま単体テストを行っているような状況でして…

    ファイルが開けなかったらそもそもファイルが読み込めなくないか?とは疑問に思ってました…

    キャンセル

  • 2017/09/15 16:52

    例外処置の基本として「業務エラー」と「例外」分けて処理するというのがあります。今回の話は「業務エラー」として処置する話ではないかと思います。詳しくはコメント欄に書ききれませんので、回答欄に追記しておきます。

    キャンセル

  • 2017/09/15 17:05

    わざわざありがとうございます…!
    try-catchってあんまり書かない方がいいんですね…初めて知りました…
    まだ業務には入っていないんですけど業務に入ったらSurferさんの話を参考にしてテストしていきたいと思います。

    今回の2つの場合はこの話で行くと例外の方になるんですかね?
    プリンター側の問題かファイル側の問題だからテストで再現するのは難しいってことですかね?

    キャンセル

  • 2017/09/15 17:16

    > 今回の2つの場合はこの話で行くと例外の方になるんですかね?

    そのあたりは質問者さんの状況・事情によるので当方は何とも言えませんが、例えば(あくまで例えばです)「ファイルが読み込めなかった場合」というのが、

    (1) ユーザーのファイル名等の選択ミスでユーザーが選択をやり直せば正しい業務フローに戻せるなら「業務エラー」として対応し、ユーザーに選択の変更を促す、

    (2) ファイルサーバーの障害等でユーザーが何とも対処できないような場合は「例外」としてランタイムに拾わせてアプリケーションを停止させる

    ・・・ということになると思います。

    キャンセル

  • 2017/09/15 17:28

    なるほど…
    今回の状況だとreadlineは業務エラーでdrawstringは例外っぽいです

    ご丁寧にありがとうございました。BAにさせていただきます。

    キャンセル

0

どちらもコードをいじらずに例外を発生するのは難しいと思います。

まず、発生しうる例外を確認します。
StreamReader.ReadLine メソッド → 例外セクション
I/Oエラーとメモリ不足で例外を発生できるようです。

Graphics.DrawString メソッド (String, Font, Brush, Single, Single) → 例外セクション
描画文字列またはBrushがnullの場合発生するようです。

次に、この例外を発生できる方法を想像します。
ReadLine の場合、ネットワーク上のファイルを対象とし、読み込み途中でネットワークを切ったりしてみてはどうでしょうか?
DrawString の場合、思いつきません...

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/15 16:26

    ネットワーク上のファイルというと例えばデスクトップ上に保存しているフォルダの中のファイルとかでしょうか?
    自分もMSDNで例外条件を調べてDrawStringの例外の発生のさせ方が思いつかなくて…w

    キャンセル

  • 2017/09/15 16:34

    共有フォルダ上のファイルです。
    ネットワークを切った時に参照できなくなるファイルですね。
    それでも、キャッシュの影響があるでしょうから、ある程度大きなサイズのファイルである必要もあるかもしれません。

    キャンセル

  • 2017/09/15 16:45

    ふむふむ…なるほど
    教えていただきありがとうございます、参考にさせてもらいます!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.76%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    POI でシートの削除を行うと後続シートのページ設定が消えてしまう(java)

    POI でシートの削除を行うとページ設定が消えてしまう(java) javaでExcelファイル(xls形式)のテンプレートファイルを読込み、編集して保存する処理を作成してい

  • 解決済

    VB.NETでデータを保持したい

    Visual Studioを使いVB.NETでウィンドウズアプリケーションを作成しています。 DataGridViewを配置し、CSVを開きそのデータをDataGridView

  • 解決済

    C# HTMLタグを除去したい

    実現したいこと HTMLタグ(<!--~-->の中身/</a>・</span>・</b>)などの除去の仕方がわかりません。どう処理したらいいのでしょうか。取得はHTML Agili

  • 解決済

    C# SeleniumでChromeを操作できない

    Seleniumを使って、Chromeを開いてgoogleを起動したいと思っているのですが、実行するとChromeが起動し、"data:,"というページが開かれた後、突然、chro

  • 解決済

    WPF:DateGrid セルの取得について

    DataGrigdを使用している中で、セルのColoum,row,値の情報がほしいのですが、 どしても、値が取得できません。 以下コードで試しましたが、どうしてもNullになってし

  • 解決済

    EPPluseを使用して出力したエクセルで自動計算させたい

    現在Visual Studio 2012を使用して開発を行っており、 準備したテンプレートのエクセルにEPPluseを使用してデータを挿入しています。 そのテンプレートのエクセルに

  • 解決済

    ListView ヘッダ部の背景色の指定

    C#(visual studio 2010)にて、ListViewをつかった表を作成しております。 ヘッダ部およびデータ部へ情報の表示はできたのですが、 ListViewヘッダ部の

  • 解決済

    C#+SeleniumでStaleElementReferenceError

    C#でSeleniumを使用して自動化処理を書いています。 (ブラウザはChromeです。) OS: Windows10 IDE: Visual Studio 2015 Sel

同じタグがついた質問を見る

  • C#

    6563questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Visual Studio 2012

    90questions

    Microsoft Visual Studio 2012は、Microsoftによる統合開発環境(IDE)であり、多種多様なプログラミング言語に対応しています。 Visual Studio 2010の次のバージョンです