いくつかのログにメッセージを書き込むクラスがあります。このクラスは、他に何もしないユーティリティであり、バックグラウンドで実行され、いくつかのことをチェックしてログに記録します。実際に何を書いているかを気にせずに、ログが書き込まれたことを単体テストで確認できるかどうか疑問に思っています。テストされている私のクラスは次のとおりです。
//imports...
public class MyClass {
private static Log log = LogFactory.getLog(MyClass.class);
public MyClass() {
log.info("MyClass is being created.");
}
public void doThing() {
if( everything_is_fine ) {
log.info("This is a message to say everything is fine.");
} else {
log.error("Uh oh...");
}
}
}
そして私のテスタークラス:
// imports ...
@RunWith(PowerMockRunner.class)
@PrepareForTest({MyClass.class,LogFactory.class})
public class MyClassTest {
Log mockLog;
@Before
public void setup() {
PowerMockito.mockStatic(LogFactory.class);
mockLog = mock(Log.class);
PowerMockito.when(LogFactory.getLog(MyClass.class)).thenReturn(mockLog);
}
@Test
public void test_everything_is_ok() {
MyClass mything = new MyClass(); // should write to log.info
mything.doThing(); // should write to log.info
verify(mockLog, atLeastOnce()).info(anyString());
verify(mockLog, never()).error(anyString());
}
@Test
public void test_everything_is_not_ok() {
MyClass mything = new MyClass(); // should write to log.info
// do something which makes things not ok
mything.doThing(); // should write to log.error
verify(mockLog, atLeastOnce()).info(anyString());
verify(mockLog, atLeastOnce()).error(anyString());
}
}
テストを実行すると、log.info() が両方のテストで呼び出され、log.error() が 2 番目のテストでのみ呼び出されることが予想されます。ただし、両方のテストの log.info で「Wanted but not invoked」が表示されます。2番目のlog.errorの場合。したがって、
1) コードが壊れていてログに書き込まれていないか、
2) テストが壊れています。
私は自分のテストで何かを台無しにしたと思っています。おそらく本当に明らかなことです。このようなものをテストした経験がある人はいますか? ありとあらゆる助けをいただければ幸いです。
アップデート:
助けてくれた人たちのおかげで、今では解決策があります。
コードを少しいじってみたところ、ログの初期化に問題があるように見えることがわかりました。モックprivate static Log log = LogFactory.getLog(MyClass.class);
を正しく使用していないように見えたので、コンストラクターに移動すると、正常にモックされたように見え、すべてのテストが期待どおりに機能します。
public class MyClass {
private static Log log;
public MyClass() {
MyClass.log = LogFactory.getLog(MyClass.class);
log.info("MyClass is being created.");
}
// etc ...
}
今は動作していますが、最初の方法でログを初期化できなかった理由を誰か説明できますか? または、それを説明している場所を教えてください。Java がオブジェクトを初期化する方法についての私の理解にギャップがあるのか、それともモック フレームワークの制限なのかはわかりません。