Saya memiliki skenario di mana saya mengharapkan beberapa panggilan pada suatu fungsi pada objek tiruan, dan kemudian untuk jalur kode tertentu saya perlu memastikan bahwa fungsi tidak dipanggil, dan setelah itu, dipanggil. Apakah ada cara untuk melakukan ini?

EXPECT_CALL(mockObj, 1); 
foo(1);

// Expect this call at the first invocation of foo(2)
EXPECT_CALL(mockObj, 2); 
foo(2);

// These calls should not call my mockObj again, the above expectation is 
// intended for the first invocation of foo(2)
foo(2);
foo(2);

// And now, i expect it to be called
EXPECT_CALL(mockObj, 3); 
foo(3);

Saya dapat memeriksa bahwa EXPECT_CALL(mockObj, 2); dipanggil hanya beberapa kali yang diharapkan, Tetapi saya juga ingin mengonfirmasi bahwa itu dipanggil hanya pada panggilan pertama ke foo(2) dan bukan pada panggilan berikutnya ke foo(2). Bisakah Anda memberi tahu saya cara apa pun untuk mencapai ini di gmock?

1
Rajeev Mehta 12 Mei 2021, 10:24

3 jawaban

Jawaban Terbaik

Apakah Anda ingin mendapatkan sesuatu seperti ini?

EXPECT_CALL(mockObj, 1).Times(0);
EXPECT_CALL(mockObj, 2).Times(0); // #2
EXPECT_CALL(mockObj, 3); // #3

{
  EXPECT_CALL(mockObj, 1); // #1
  foo(1); // Matches #1
}

{
  EXPECT_CALL(mockObj, 2); // #4
  // Expect this call at the first invocation of foo(2)
  foo(2); // Matches #4
}

// These calls should not call my mockObj again, the above expectation is 
// intended for the first invocation of foo(2)
foo(2); // Matches #2
foo(2); // Matches #2

// And now, i expect it to be called
foo(3); // Matches #3
0
S.M. 12 Mei 2021, 15:21

Buku masak Gmock menyarankan menggunakan fungsi tiruan pos pemeriksaan dummy

using ::testing::MockFunction;

TEST(FooTest, InvokesMyMockCorrectly) {
  MyMock mockObj;
  // Class MockFunction<F> has exactly one mock method.  It is named
  // Call() and has type F.
  MockFunction<void(string check_point_name)> check;
  {
    InSequence s;

    EXPECT_CALL(mockObj, 1);
    EXPECT_CALL(check, "1");
    EXPECT_CALL(mockObj, 2);
    EXPECT_CALL(check, "2");
    EXPECT_CALL(check, "3");
    EXPECT_CALL(mockObj, 3);
  }
  
  foo(1);
  check.Call("1");

  foo(2);
  check.Call("2");

  foo(2);
  foo(2);

  check.Call("3");
  foo(3);
}

Atau gunakan Mock::VerifyAndClearExpectations() untuk mengatur ulang tiruan dan kemudian menetapkan harapan baru.

Jika tidak, menyisipkan panggilan ke tiruan dan EXPECT_CALL seperti yang disarankan dalam beberapa jawaban adalah perilaku yang tidak ditentukan:

Catatan penting: gMock mengharuskan ekspektasi ditetapkan sebelum fungsi tiruan dipanggil, jika tidak, perilaku tidak akan ditentukan. Secara khusus, Anda tidak boleh menyisipkan EXPECT_CALL()s dan memanggil fungsi tiruan.

Dari gmock for dummies , lihat juga Menyingkirkan EXPECT_CALL() dan panggilan ke tiruan fungsi

2
Ian Martin 12 Mei 2021, 10:09

Saya akan membaginya menjadi beberapa kasus uji:

TEST(Foo, CalledOnFirstInvoation) {
  EXPECT_CALL(mockObj, 1); 
  foo(1);
}

TEST(Foo, CalledAgainWhenUsingDifferenArgument) {
  EXPECT_CALL(mockObj, 2); 
  foo(1);
  foo(2);
}

TEST(Foo, NotCalledWhenUsingSameArgument) {
  EXPECT_CALL(mockObj, 2); 
  foo(1);
  foo(2);
  foo(2);
  foo(2);
}

TEST(Foo, CalledAgainWhenUsingYetAnotherArgument) {
  EXPECT_CALL(mockObj, 3); 
  foo(1);
  foo(2);
  foo(2);
  foo(3);
}
2
Georg P. 12 Mei 2021, 07:51